From 14af6b429ef2355ba0e8342c4af0f9dd9aafab1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 7 Dec 2017 23:15:05 +0100 Subject: Use ensuredir() instead of os.makedirs() to fix race conditions Use the ensuredir() function consistently across Sphinx code to avoid race conditions e.g. when multiple Sphinx instances attempt to create the same output directory. The ensuredir() function that was already present in sphinx.util.osutil correctly catches EEXIST exception that occurs if the specified directory already exists (i.e. it was created between the call to os.path.isdir() and os.makedirs() that follows it). While at it, remove redundant os.path.isdir() calls when they only guarded the os.makedirs() call, and replace mkdir_p() which had pretty much the same purpose, except for being prone to race conditions. I did not modify testing-related code as race conditions mostly affect real applications and not the test environment. Fix #4281: Race conditions when creating output directory --- sphinx/quickstart.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'sphinx/quickstart.py') diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index d23dc3b74..5d8738996 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -35,7 +35,7 @@ from six.moves.urllib.parse import quote as urlquote from docutils.utils import column_width from sphinx import __display_version__, package_dir -from sphinx.util.osutil import make_filename +from sphinx.util.osutil import ensuredir, make_filename from sphinx.util.console import ( # type: ignore purple, bold, red, turquoise, nocolor, color_terminal ) @@ -69,13 +69,6 @@ EXTENSIONS = ('autodoc', 'doctest', 'intersphinx', 'todo', 'coverage', PROMPT_PREFIX = '> ' -def mkdir_p(dir): - # type: (unicode) -> None - if path.isdir(dir): - return - os.makedirs(dir) - - # function to get input from terminal -- overridden by the test suite def term_input(prompt): # type: (unicode) -> unicode @@ -433,11 +426,11 @@ def generate(d, overwrite=True, silent=False, templatedir=None): d[key + '_str'] = d[key].replace('\\', '\\\\').replace("'", "\\'") if not path.isdir(d['path']): - mkdir_p(d['path']) + ensuredir(d['path']) srcdir = d['sep'] and path.join(d['path'], 'source') or d['path'] - mkdir_p(srcdir) + ensuredir(srcdir) if d['sep']: builddir = path.join(d['path'], 'build') d['exclude_patterns'] = '' @@ -448,9 +441,9 @@ def generate(d, overwrite=True, silent=False, templatedir=None): 'Thumbs.db', '.DS_Store', ]) d['exclude_patterns'] = ', '.join(exclude_patterns) - mkdir_p(builddir) - mkdir_p(path.join(srcdir, d['dot'] + 'templates')) - mkdir_p(path.join(srcdir, d['dot'] + 'static')) + ensuredir(builddir) + ensuredir(path.join(srcdir, d['dot'] + 'templates')) + ensuredir(path.join(srcdir, d['dot'] + 'static')) def write_file(fpath, content, newline=None): # type: (unicode, unicode, unicode) -> None -- cgit v1.2.1 From 2426cedb8b12b7a59270e55f2f26d63d0014a28f Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Mon, 1 Jan 2018 01:06:58 +0900 Subject: A happy new year! --- sphinx/quickstart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sphinx/quickstart.py') diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 5d8738996..a36c57528 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -5,7 +5,7 @@ Quickly setup documentation source to work with Sphinx. - :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from __future__ import print_function -- cgit v1.2.1