aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/portage/util/__init__.py')
-rw-r--r--lib/portage/util/__init__.py45
1 files changed, 30 insertions, 15 deletions
diff --git a/lib/portage/util/__init__.py b/lib/portage/util/__init__.py
index f338f274a..50fa1680f 100644
--- a/lib/portage/util/__init__.py
+++ b/lib/portage/util/__init__.py
@@ -1434,7 +1434,7 @@ class atomic_ofstream(AbstractContextManager, ObjectProxy):
error occurs)."""
def __init__(self, filename, mode="w", follow_links=True, **kargs):
- """Opens a temporary filename.pid in the same directory as filename."""
+ """Opens a temporary file in the same directory as filename."""
ObjectProxy.__init__(self)
object.__setattr__(self, "_aborted", False)
if "b" in mode:
@@ -1447,10 +1447,11 @@ class atomic_ofstream(AbstractContextManager, ObjectProxy):
if follow_links:
canonical_path = os.path.realpath(filename)
object.__setattr__(self, "_real_name", canonical_path)
- parent, basename = os.path.split(canonical_path)
- fd, tmp_name = tempfile.mkstemp(prefix=basename, dir=parent)
- object.__setattr__(self, "_tmp_name", tmp_name)
+ fd = None
try:
+ parent, basename = os.path.split(canonical_path)
+ fd, tmp_name = tempfile.mkstemp(prefix=basename, dir=parent)
+ object.__setattr__(self, "_tmp_name", tmp_name)
object.__setattr__(
self,
"_file",
@@ -1462,7 +1463,8 @@ class atomic_ofstream(AbstractContextManager, ObjectProxy):
)
return
except OSError:
- os.close(fd)
+ if fd is not None:
+ os.close(fd)
if canonical_path == filename:
raise
# Ignore this error, since it's irrelevant
@@ -1470,10 +1472,11 @@ class atomic_ofstream(AbstractContextManager, ObjectProxy):
# new error if necessary.
object.__setattr__(self, "_real_name", filename)
- parent, basename = os.path.split(filename)
- fd, tmp_name = tempfile.mkstemp(prefix=basename, dir=parent)
- object.__setattr__(self, "_tmp_name", tmp_name)
+ fd = None
try:
+ parent, basename = os.path.split(filename)
+ fd, tmp_name = tempfile.mkstemp(prefix=basename, dir=parent)
+ object.__setattr__(self, "_tmp_name", tmp_name)
object.__setattr__(
self,
"_file",
@@ -1484,7 +1487,8 @@ class atomic_ofstream(AbstractContextManager, ObjectProxy):
),
)
except OSError:
- os.close(fd)
+ if fd is not None:
+ os.close(fd)
raise
def __exit__(self, exc_type, exc_val, exc_tb):
@@ -1505,15 +1509,26 @@ class atomic_ofstream(AbstractContextManager, ObjectProxy):
"""Closes the temporary file, copies permissions (if possible),
and performs the atomic replacement via os.rename(). If the abort()
method has been called, then the temp file is closed and removed."""
- f = object.__getattribute__(self, "_file")
- tmp_name = object.__getattribute__(self, "_tmp_name")
- real_name = object.__getattribute__(self, "_real_name")
- if not f.closed:
+ try:
+ f = object.__getattribute__(self, "_file")
+ except AttributeError:
+ f = None
+ if f is not None and not f.closed:
+ real_name = object.__getattribute__(self, "_real_name")
+ tmp_name = object.__getattribute__(self, "_tmp_name")
try:
f.close()
if not object.__getattribute__(self, "_aborted"):
try:
- apply_stat_permissions(tmp_name, os.stat(real_name))
+ try:
+ st = os.stat(real_name)
+ except FileNotFoundError:
+ umask_test_file = f"{tmp_name}_umask_test"
+ with open(umask_test_file, "w") as f:
+ st = os.fstat(f.fileno())
+ os.unlink(umask_test_file)
+
+ apply_stat_permissions(tmp_name, st)
except OperationNotPermitted:
pass
except FileNotFound:
@@ -1529,7 +1544,7 @@ class atomic_ofstream(AbstractContextManager, ObjectProxy):
# even if an exception is raised.
try:
os.unlink(tmp_name)
- except OSError as oe:
+ except OSError:
pass
def abort(self):