|
1 diff --git Python-2.6.4/Python/import.c Python-2.6.4/Python/import.c |
|
2 --- Python-2.6.4/Python/import.c |
|
3 +++ Python-2.6.4/Python/import.c |
|
4 @@ -866,8 +866,9 @@ |
|
5 |
|
6 /* Write a compiled module to a file, placing the time of last |
|
7 modification of its source into the header. |
|
8 - Errors are ignored, if a write error occurs an attempt is made to |
|
9 - remove the file. */ |
|
10 + Write to a temporary file first so that creating the file is atomic. |
|
11 + Errors are ignored, if a write/unlink/rename error occurs an attempt |
|
12 + is made to remove the temporary file. */ |
|
13 |
|
14 static void |
|
15 write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat) |
|
16 @@ -879,12 +880,21 @@ |
|
17 #else |
|
18 mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH; |
|
19 #endif |
|
20 + char *tmppathname; |
|
21 + |
|
22 + /* the temporary file is called cpathname + ".tmp" */ |
|
23 + if ((tmppathname = PyMem_Malloc(strlen(cpathname) + strlen(".tmp") + 1)) |
|
24 + == NULL) { |
|
25 + return; |
|
26 + } |
|
27 + sprintf (tmppathname, "%s.tmp", cpathname); |
|
28 + fp = open_exclusive(tmppathname, mode); |
|
29 |
|
30 - fp = open_exclusive(cpathname, mode); |
|
31 if (fp == NULL) { |
|
32 if (Py_VerboseFlag) |
|
33 PySys_WriteStderr( |
|
34 - "# can't create %s\n", cpathname); |
|
35 + "# can't create %s\n", tmppathname); |
|
36 + PyMem_Free(tmppathname); |
|
37 return; |
|
38 } |
|
39 PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION); |
|
40 @@ -893,10 +903,11 @@ |
|
41 PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION); |
|
42 if (fflush(fp) != 0 || ferror(fp)) { |
|
43 if (Py_VerboseFlag) |
|
44 - PySys_WriteStderr("# can't write %s\n", cpathname); |
|
45 + PySys_WriteStderr("# can't write %s\n", tmppathname); |
|
46 /* Don't keep partial file */ |
|
47 fclose(fp); |
|
48 - (void) unlink(cpathname); |
|
49 + (void) unlink(tmppathname); |
|
50 + PyMem_Free(tmppathname); |
|
51 return; |
|
52 } |
|
53 /* Now write the true mtime */ |
|
54 @@ -905,8 +916,30 @@ |
|
55 PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION); |
|
56 fflush(fp); |
|
57 fclose(fp); |
|
58 + /* Delete the old compiled file, if exists */ |
|
59 + if (unlink (cpathname)) { |
|
60 + if ((errno != ENOENT)) { |
|
61 + /* the file exists but could not be deleted */ |
|
62 + if (Py_VerboseFlag) |
|
63 + PySys_WriteStderr( |
|
64 + "# can't unlink %s\n", cpathname); |
|
65 + (void) unlink(tmppathname); |
|
66 + PyMem_Free(tmppathname); |
|
67 + return; |
|
68 + } |
|
69 + } |
|
70 + /* rename the tmp file to the real file name */ |
|
71 + if (rename (tmppathname, cpathname)) { |
|
72 + if (Py_VerboseFlag) |
|
73 + PySys_WriteStderr( |
|
74 + "# can't rename %s to %s\n", tmppathname, cpathname); |
|
75 + (void) unlink(tmppathname); |
|
76 + PyMem_Free(tmppathname); |
|
77 + return; |
|
78 + } |
|
79 if (Py_VerboseFlag) |
|
80 PySys_WriteStderr("# wrote %s\n", cpathname); |
|
81 + PyMem_Free(tmppathname); |
|
82 } |
|
83 |
|
84 static void |