util: make ensuredirs safer against races

This commit is contained in:
Bryan O'Sullivan 2013-02-13 12:20:10 -08:00
parent e35379ebe6
commit 9b9339ed49
2 changed files with 11 additions and 8 deletions

View File

@ -306,8 +306,7 @@ class vfs(abstractvfs):
# to a directory. Let the posixfile() call below raise IOError.
if basename:
if atomictemp:
if not os.path.isdir(dirname):
util.ensuredirs(dirname, self.createmode)
util.ensuredirs(dirname, self.createmode)
return util.atomictempfile(f, mode, self.createmode)
try:
if 'w' in mode:
@ -325,8 +324,7 @@ class vfs(abstractvfs):
if e.errno != errno.ENOENT:
raise
nlink = 0
if not os.path.isdir(dirname):
util.ensuredirs(dirname, self.createmode)
util.ensuredirs(dirname, self.createmode)
if nlink > 0:
if self._trustnlink is None:
self._trustnlink = nlink > 1 or util.checknlink(f)
@ -345,9 +343,7 @@ class vfs(abstractvfs):
except OSError:
pass
dirname = os.path.dirname(linkname)
if not os.path.exists(dirname):
util.ensuredirs(dirname, self.createmode)
util.ensuredirs(os.path.dirname(linkname), self.createmode)
if self._cansymlink:
try:

View File

@ -882,13 +882,20 @@ def makedirs(name, mode=None):
def ensuredirs(name, mode=None):
"""race-safe recursive directory creation"""
if os.path.isdir(name):
return
parent = os.path.dirname(os.path.abspath(name))
if parent != name:
ensuredirs(parent, mode)
try:
makedirs(name, mode)
os.mkdir(name)
except OSError, err:
if err.errno == errno.EEXIST and os.path.isdir(name):
# someone else seems to have won a directory creation race
return
raise
if mode is not None:
os.chmod(name, mode)
def readfile(path):
fp = open(path, 'rb')