mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-117467: Add preserving of mailbox owner on flush (GH-117510)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
dc54714044
commit
3f5bcc86d0
3 changed files with 51 additions and 3 deletions
|
@ -750,9 +750,13 @@ class _singlefileMailbox(Mailbox):
|
||||||
_sync_close(new_file)
|
_sync_close(new_file)
|
||||||
# self._file is about to get replaced, so no need to sync.
|
# self._file is about to get replaced, so no need to sync.
|
||||||
self._file.close()
|
self._file.close()
|
||||||
# Make sure the new file's mode is the same as the old file's
|
# Make sure the new file's mode and owner are the same as the old file's
|
||||||
mode = os.stat(self._path).st_mode
|
info = os.stat(self._path)
|
||||||
os.chmod(new_file.name, mode)
|
os.chmod(new_file.name, info.st_mode)
|
||||||
|
try:
|
||||||
|
os.chown(new_file.name, info.st_uid, info.st_gid)
|
||||||
|
except (AttributeError, OSError):
|
||||||
|
pass
|
||||||
try:
|
try:
|
||||||
os.rename(new_file.name, self._path)
|
os.rename(new_file.name, self._path)
|
||||||
except FileExistsError:
|
except FileExistsError:
|
||||||
|
|
|
@ -9,6 +9,7 @@ import re
|
||||||
import io
|
import io
|
||||||
import tempfile
|
import tempfile
|
||||||
from test import support
|
from test import support
|
||||||
|
from test.support import import_helper
|
||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
from test.support import refleak_helper
|
from test.support import refleak_helper
|
||||||
from test.support import socket_helper
|
from test.support import socket_helper
|
||||||
|
@ -1081,6 +1082,47 @@ class _TestSingleFile(TestMailbox):
|
||||||
|
|
||||||
self.assertEqual(os.stat(self._path).st_mode, mode)
|
self.assertEqual(os.stat(self._path).st_mode, mode)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(os, 'chown'), 'requires os.chown')
|
||||||
|
def test_ownership_after_flush(self):
|
||||||
|
# See issue gh-117467
|
||||||
|
|
||||||
|
pwd = import_helper.import_module('pwd')
|
||||||
|
grp = import_helper.import_module('grp')
|
||||||
|
st = os.stat(self._path)
|
||||||
|
|
||||||
|
for e in pwd.getpwall():
|
||||||
|
if e.pw_uid != st.st_uid:
|
||||||
|
other_uid = e.pw_uid
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.skipTest("test needs more than one user")
|
||||||
|
|
||||||
|
for e in grp.getgrall():
|
||||||
|
if e.gr_gid != st.st_gid:
|
||||||
|
other_gid = e.gr_gid
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.skipTest("test needs more than one group")
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.chown(self._path, other_uid, other_gid)
|
||||||
|
except OSError:
|
||||||
|
self.skipTest('test needs root privilege')
|
||||||
|
# Change permissions as in test_permissions_after_flush.
|
||||||
|
mode = st.st_mode | 0o666
|
||||||
|
os.chmod(self._path, mode)
|
||||||
|
|
||||||
|
self._box.add(self._template % 0)
|
||||||
|
i = self._box.add(self._template % 1)
|
||||||
|
# Need to remove one message to make flush() create a new file
|
||||||
|
self._box.remove(i)
|
||||||
|
self._box.flush()
|
||||||
|
|
||||||
|
st = os.stat(self._path)
|
||||||
|
self.assertEqual(st.st_uid, other_uid)
|
||||||
|
self.assertEqual(st.st_gid, other_gid)
|
||||||
|
self.assertEqual(st.st_mode, mode)
|
||||||
|
|
||||||
|
|
||||||
class _TestMboxMMDF(_TestSingleFile):
|
class _TestMboxMMDF(_TestSingleFile):
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Preserve mailbox ownership when rewriting in :func:`mailbox.mbox.flush`.
|
||||||
|
Patch by Tony Mountifield.
|
Loading…
Add table
Add a link
Reference in a new issue