TASK-021: Implement atomic writes for set_jail_config_enabled and write_jail_config_file
This commit is contained in:
@@ -257,3 +257,38 @@ def _create_conf_file(subdir: Path, name: str, content: str) -> str:
|
||||
raise ConfigFileWriteError(f"Cannot create {name!r}: {exc}") from exc
|
||||
|
||||
return target.name
|
||||
|
||||
|
||||
def atomic_write(path: Path, content: str) -> None:
|
||||
"""Write content to a file atomically using temp file + rename.
|
||||
|
||||
This function ensures that if the process is killed during the write,
|
||||
the target file is not corrupted. Uses a temporary file in the same
|
||||
directory as the target, then atomically renames it into place.
|
||||
|
||||
Args:
|
||||
path: Target file path.
|
||||
content: Content to write.
|
||||
|
||||
Raises:
|
||||
ConfigFileWriteError: If the file cannot be written.
|
||||
"""
|
||||
_validate_content(content)
|
||||
|
||||
tmp_name: str | None = None
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(
|
||||
mode="w",
|
||||
encoding="utf-8",
|
||||
dir=path.parent,
|
||||
delete=False,
|
||||
suffix=".tmp",
|
||||
) as tmp:
|
||||
tmp.write(content)
|
||||
tmp_name = tmp.name
|
||||
os.replace(tmp_name, path)
|
||||
except OSError as exc:
|
||||
with contextlib.suppress(OSError):
|
||||
if tmp_name is not None:
|
||||
os.unlink(tmp_name)
|
||||
raise ConfigFileWriteError(f"Cannot write {path.name!r}: {exc}") from exc
|
||||
|
||||
Reference in New Issue
Block a user