Fix Maildir race
fixes deb#439384 From: martin f krafft Subject: race condition in Maildir writing The offlineimap Maildir code checks for file existence and then opens a file. That's open to a race condition. It's better to open the file and fail if it already exists. The following patch does this. It catches OSError 17 (file exists) and re-raises all others. I'll leave it up to you to decide whether this is appropriate.
This commit is contained in:
parent
c476e8c98c
commit
6caaea36e0
@ -158,7 +158,8 @@ class MaildirFolder(BaseFolder):
|
|||||||
# Otherwise, save the message in tmp/ and then call savemessageflags()
|
# Otherwise, save the message in tmp/ and then call savemessageflags()
|
||||||
# to give it a permanent home.
|
# to give it a permanent home.
|
||||||
tmpdir = os.path.join(self.getfullname(), 'tmp')
|
tmpdir = os.path.join(self.getfullname(), 'tmp')
|
||||||
messagename = None
|
file = fd = None
|
||||||
|
messagename = tmpmessaename = None
|
||||||
attempts = 0
|
attempts = 0
|
||||||
while 1:
|
while 1:
|
||||||
if attempts > 15:
|
if attempts > 15:
|
||||||
@ -171,19 +172,24 @@ class MaildirFolder(BaseFolder):
|
|||||||
socket.gethostname(),
|
socket.gethostname(),
|
||||||
uid,
|
uid,
|
||||||
md5.new(self.getvisiblename()).hexdigest())
|
md5.new(self.getvisiblename()).hexdigest())
|
||||||
if os.path.exists(os.path.join(tmpdir, messagename)):
|
tmpmessagename = messagename.split(',')[0]
|
||||||
time.sleep(2)
|
try:
|
||||||
attempts += 1
|
fd = os.open(os.path.join(tmpdir, tmpmessagename),
|
||||||
else:
|
os.O_WRONLY + os.O_CREAT + os.O_EXCL)
|
||||||
break
|
file = os.fdopen(fd, 'w')
|
||||||
tmpmessagename = messagename.split(',')[0]
|
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
||||||
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
except OSError, e:
|
||||||
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
if e.errno == 17:
|
||||||
|
time.sleep(2)
|
||||||
|
attempts += 1
|
||||||
|
continue
|
||||||
|
raise
|
||||||
|
|
||||||
file.write(content)
|
file.write(content)
|
||||||
|
|
||||||
# Make sure the data hits the disk
|
# Make sure the data hits the disk
|
||||||
file.flush()
|
file.flush()
|
||||||
os.fsync(file.fileno())
|
os.fsync(fd)
|
||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
if rtime != None:
|
if rtime != None:
|
||||||
|
Loading…
Reference in New Issue
Block a user