diff options
author | Guido van Rossum <guido@python.org> | 2000-09-20 20:31:38 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2000-09-20 20:31:38 (GMT) |
commit | 55a8338d7fed65d3e0bdcf9c68f65bcbeb06ba50 (patch) | |
tree | 7937e94050c872928729cf34aa2a3b1f2ad8bd05 /Python | |
parent | 6c0f33f8efdd3e288a66402c8c1c38622206bcb2 (diff) | |
download | cpython-55a8338d7fed65d3e0bdcf9c68f65bcbeb06ba50.zip cpython-55a8338d7fed65d3e0bdcf9c68f65bcbeb06ba50.tar.gz cpython-55a8338d7fed65d3e0bdcf9c68f65bcbeb06ba50.tar.bz2 |
On Unix, use O_EXCL when creating the .pyc/.pyo files, to avoid a race condition
Diffstat (limited to 'Python')
-rw-r--r-- | Python/import.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/Python/import.c b/Python/import.c index 9d65c70..533f85e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -28,12 +28,17 @@ #ifndef DONT_HAVE_SYS_TYPES_H #include <sys/types.h> #endif + #ifndef DONT_HAVE_SYS_STAT_H #include <sys/stat.h> #elif defined(HAVE_STAT_H) #include <stat.h> #endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + #if defined(PYCC_VACPP) /* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */ #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 modification of its source into the header. 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; - fp = fopen(cpathname, "wb"); + fp = open_exclusive(cpathname); if (fp == NULL) { if (Py_VerboseFlag) PySys_WriteStderr( |