On Unix, use O_EXCL when creating the .pyc/.pyo files, to avoid a race condition
This commit is contained in:
parent
6c0f33f8ef
commit
55a8338d7f
|
@ -28,12 +28,17 @@
|
||||||
#ifndef DONT_HAVE_SYS_TYPES_H
|
#ifndef DONT_HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DONT_HAVE_SYS_STAT_H
|
#ifndef DONT_HAVE_SYS_STAT_H
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#elif defined(HAVE_STAT_H)
|
#elif defined(HAVE_STAT_H)
|
||||||
#include <stat.h>
|
#include <stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(PYCC_VACPP)
|
#if defined(PYCC_VACPP)
|
||||||
/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */
|
/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */
|
||||||
#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG)
|
#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG)
|
||||||
|
@ -627,6 +632,31 @@ parse_source_module(char *pathname, FILE *fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper to open a bytecode file for writing in exclusive mode */
|
||||||
|
|
||||||
|
static FILE *
|
||||||
|
open_exclusive(char *filename)
|
||||||
|
{
|
||||||
|
#if defined(O_EXCL)&&defined(O_CREAT)&&defined(O_WRONLY)&&defined(O_TRUNC)
|
||||||
|
/* Use O_EXCL to avoid a race condition when another process tries to
|
||||||
|
write the same file. When that happens, our open() call fails,
|
||||||
|
which is just fine (since it's only a cache).
|
||||||
|
XXX If the file exists and is writable but the directory is not
|
||||||
|
writable, the file will never be written. Oh well.
|
||||||
|
*/
|
||||||
|
int fd;
|
||||||
|
(void) unlink(filename);
|
||||||
|
fd = open(filename, O_EXCL|O_CREAT|O_WRONLY|O_TRUNC, 0666);
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
return fdopen(fd, "wb");
|
||||||
|
#else
|
||||||
|
/* Best we can do -- on Windows this can't happen anyway */
|
||||||
|
return fopen(filename, "wb");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write a compiled module to a file, placing the time of last
|
/* Write a compiled module to a file, placing the time of last
|
||||||
modification of its source into the header.
|
modification of its source into the header.
|
||||||
Errors are ignored, if a write error occurs an attempt is made to
|
Errors are ignored, if a write error occurs an attempt is made to
|
||||||
|
@ -637,7 +667,7 @@ write_compiled_module(PyCodeObject *co, char *cpathname, long mtime)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
fp = fopen(cpathname, "wb");
|
fp = open_exclusive(cpathname);
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
if (Py_VerboseFlag)
|
if (Py_VerboseFlag)
|
||||||
PySys_WriteStderr(
|
PySys_WriteStderr(
|
||||||
|
|
Loading…
Reference in New Issue