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()
|
||||
# to give it a permanent home.
|
||||
tmpdir = os.path.join(self.getfullname(), 'tmp')
|
||||
messagename = None
|
||||
file = fd = None
|
||||
messagename = tmpmessaename = None
|
||||
attempts = 0
|
||||
while 1:
|
||||
if attempts > 15:
|
||||
@ -171,19 +172,24 @@ class MaildirFolder(BaseFolder):
|
||||
socket.gethostname(),
|
||||
uid,
|
||||
md5.new(self.getvisiblename()).hexdigest())
|
||||
if os.path.exists(os.path.join(tmpdir, messagename)):
|
||||
time.sleep(2)
|
||||
attempts += 1
|
||||
else:
|
||||
break
|
||||
tmpmessagename = messagename.split(',')[0]
|
||||
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
||||
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
||||
tmpmessagename = messagename.split(',')[0]
|
||||
try:
|
||||
fd = os.open(os.path.join(tmpdir, tmpmessagename),
|
||||
os.O_WRONLY + os.O_CREAT + os.O_EXCL)
|
||||
file = os.fdopen(fd, 'w')
|
||||
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
||||
except OSError, e:
|
||||
if e.errno == 17:
|
||||
time.sleep(2)
|
||||
attempts += 1
|
||||
continue
|
||||
raise
|
||||
|
||||
file.write(content)
|
||||
|
||||
# Make sure the data hits the disk
|
||||
file.flush()
|
||||
os.fsync(file.fileno())
|
||||
os.fsync(fd)
|
||||
|
||||
file.close()
|
||||
if rtime != None:
|
||||
|
Loading…
Reference in New Issue
Block a user