Files
Elydora-Python-SDK/elydora/plugins/_pinned_directory.py
T
雷电芽衣 ed34831c20 chore(python): audit plugins shared modules
_managed_files owns the file snapshot reader and public metadata helpers used by pinned directories, durable copies, and opaque snapshots; transaction staging owns read_target and same_identity_and_contents; dead helpers removed; hook_template no longer re-exports the guard generator; mypy targets win32 so _windows_security type-checks.

Claude-Session: https://claude.ai/code/session_01Agoc9bRVE9KL7mmWtey9Vq
2026-09-02 23:16:15 -04:00

450 lines
16 KiB
Python

"""Pinned physical directory handles for transactional file operations."""
from __future__ import annotations
from dataclasses import dataclass
import os
import stat
from typing import Any, Optional, Tuple
from ._managed_files import (
DirectorySnapshot,
FileSnapshot,
read_file_snapshot,
read_physical_directory,
)
_FILE_ATTRIBUTE_DIRECTORY = 0x00000010
_FILE_ATTRIBUTE_NORMAL = 0x00000080
_FILE_ATTRIBUTE_READONLY = 0x00000001
_FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
def _close_windows_handle(handle: int) -> None:
import ctypes as ctypes_module
from ctypes import wintypes
ctypes: Any = ctypes_module
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
close_handle = kernel32.CloseHandle
close_handle.argtypes = [wintypes.HANDLE]
close_handle.restype = wintypes.BOOL
if not close_handle(handle):
error = ctypes.get_last_error()
raise OSError(f"Close Windows handle: {ctypes.WinError(error)}")
def _open_windows_directory(
directory: str, label: str, delete_access: bool = False
) -> Tuple[int, DirectorySnapshot]:
import ctypes as ctypes_module
from ctypes import wintypes
import msvcrt as msvcrt_module
ctypes: Any = ctypes_module
msvcrt: Any = msvcrt_module
class ByHandleFileInformation(ctypes.Structure):
_fields_ = [
("file_attributes", wintypes.DWORD),
("creation_time", wintypes.FILETIME),
("last_access_time", wintypes.FILETIME),
("last_write_time", wintypes.FILETIME),
("volume_serial_number", wintypes.DWORD),
("file_size_high", wintypes.DWORD),
("file_size_low", wintypes.DWORD),
("number_of_links", wintypes.DWORD),
("file_index_high", wintypes.DWORD),
("file_index_low", wintypes.DWORD),
]
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
create_file = kernel32.CreateFileW
create_file.argtypes = [
wintypes.LPCWSTR,
wintypes.DWORD,
wintypes.DWORD,
wintypes.LPVOID,
wintypes.DWORD,
wintypes.DWORD,
wintypes.HANDLE,
]
create_file.restype = wintypes.HANDLE
get_information = kernel32.GetFileInformationByHandle
get_information.argtypes = [
wintypes.HANDLE,
ctypes.POINTER(ByHandleFileInformation),
]
get_information.restype = wintypes.BOOL
file_list_directory = 0x00000001
file_read_attributes = 0x00000080
delete = 0x00010000
file_share_read = 0x00000001
file_share_write = 0x00000002
open_existing = 3
file_flag_open_reparse_point = 0x00200000
file_flag_backup_semantics = 0x02000000
invalid_handle = ctypes.c_void_p(-1).value
handle = create_file(
directory,
file_list_directory
| file_read_attributes
| (delete if delete_access else 0),
file_share_read | file_share_write,
None,
open_existing,
file_flag_open_reparse_point | file_flag_backup_semantics,
None,
)
if handle == invalid_handle:
error = ctypes.get_last_error()
raise OSError(f"Open {label} at {directory}: {ctypes.WinError(error)}")
handle_value = int(handle)
descriptor = -1
try:
information = ByHandleFileInformation()
if not get_information(handle_value, ctypes.byref(information)):
error = ctypes.get_last_error()
raise OSError(
f"Inspect pinned {label} at {directory}: {ctypes.WinError(error)}"
)
attributes = information.file_attributes
if not attributes & _FILE_ATTRIBUTE_DIRECTORY:
raise OSError(f"{label} is not a physical directory: {directory}")
if attributes & _FILE_ATTRIBUTE_REPARSE_POINT:
raise OSError(f"{label} is not a physical directory: {directory}")
descriptor = msvcrt.open_osfhandle(
handle_value,
os.O_RDONLY | getattr(os, "O_NOINHERIT", 0),
)
handle_value = 0
metadata = os.fstat(descriptor)
if not stat.S_ISDIR(metadata.st_mode):
raise OSError(f"{label} is not a physical directory: {directory}")
return descriptor, DirectorySnapshot(metadata.st_dev, metadata.st_ino)
except Exception:
if descriptor >= 0:
os.close(descriptor)
elif handle_value:
_close_windows_handle(handle_value)
raise
def _chmod_windows_descriptor(descriptor: int, mode: int) -> None:
import ctypes as ctypes_module
from ctypes import wintypes
import msvcrt as msvcrt_module
ctypes: Any = ctypes_module
msvcrt: Any = msvcrt_module
class FileBasicInformation(ctypes.Structure):
_fields_ = [
("creation_time", ctypes.c_longlong),
("last_access_time", ctypes.c_longlong),
("last_write_time", ctypes.c_longlong),
("change_time", ctypes.c_longlong),
("file_attributes", wintypes.DWORD),
]
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
get_information = kernel32.GetFileInformationByHandleEx
get_information.argtypes = [
wintypes.HANDLE,
ctypes.c_int,
wintypes.LPVOID,
wintypes.DWORD,
]
get_information.restype = wintypes.BOOL
set_information = kernel32.SetFileInformationByHandle
set_information.argtypes = [
wintypes.HANDLE,
ctypes.c_int,
wintypes.LPVOID,
wintypes.DWORD,
]
set_information.restype = wintypes.BOOL
handle = msvcrt.get_osfhandle(descriptor)
if handle == -1:
raise OSError("File descriptor has no Windows handle")
current = FileBasicInformation()
file_basic_info = 0
if not get_information(
handle,
file_basic_info,
ctypes.byref(current),
ctypes.sizeof(current),
):
error = ctypes.get_last_error()
raise OSError(f"Inspect open file mode: {ctypes.WinError(error)}")
attributes = int(current.file_attributes)
if mode & stat.S_IWRITE:
attributes &= ~_FILE_ATTRIBUTE_READONLY
if attributes == 0:
attributes = _FILE_ATTRIBUTE_NORMAL
else:
attributes &= ~_FILE_ATTRIBUTE_NORMAL
attributes |= _FILE_ATTRIBUTE_READONLY
if attributes == current.file_attributes:
return
update = FileBasicInformation(0, 0, 0, 0, attributes)
if not set_information(
handle,
file_basic_info,
ctypes.byref(update),
ctypes.sizeof(update),
):
error = ctypes.get_last_error()
raise OSError(f"Set open file mode: {ctypes.WinError(error)}")
def chmod_open_file(descriptor: int, mode: int) -> None:
"""Apply a mode to the already-open physical file."""
if os.name == "nt" and not hasattr(os, "fchmod"):
_chmod_windows_descriptor(descriptor, mode)
return
getattr(os, "fchmod")(descriptor, mode)
@dataclass
class PinnedDirectory:
"""Keep one physical directory stable while path mutations run."""
path: str
label: str
snapshot: DirectorySnapshot
descriptor: Optional[int] = None
path_bound: bool = True
@classmethod
def open(
cls,
directory: str,
label: str,
expected: Optional[DirectorySnapshot] = None,
delete_access: bool = False,
) -> "PinnedDirectory":
normalized = os.path.abspath(directory)
before = read_physical_directory(normalized, label)
if before is None:
raise OSError(f"{label} is missing: {normalized}")
if expected is not None and before != expected:
raise OSError(f"{label} changed before pinning: {normalized}")
descriptor: Optional[int] = None
try:
if os.name == "nt":
if delete_access:
descriptor, opened = _open_windows_directory(
normalized, label, True
)
else:
descriptor, opened = _open_windows_directory(
normalized, label
)
if opened != before:
raise OSError(f"{label} changed while pinning: {normalized}")
else:
flags = (
os.O_RDONLY
| getattr(os, "O_CLOEXEC", 0)
| getattr(os, "O_DIRECTORY", 0)
| getattr(os, "O_NOFOLLOW", 0)
)
descriptor = os.open(normalized, flags)
metadata = os.fstat(descriptor)
if (
not stat.S_ISDIR(metadata.st_mode)
or (metadata.st_dev, metadata.st_ino)
!= (before.device, before.inode)
):
raise OSError(f"{label} changed while pinning: {normalized}")
after = read_physical_directory(normalized, label)
if after != before:
raise OSError(f"{label} changed while pinning: {normalized}")
return cls(normalized, label, before, descriptor)
except Exception:
if descriptor is not None:
os.close(descriptor)
raise
def close(self) -> None:
failures = []
if self.descriptor is not None:
try:
os.close(self.descriptor)
except OSError as error:
failures.append(str(error))
self.descriptor = None
if failures:
raise OSError(f"Close {self.label}: {'; '.join(failures)}")
def _require_open(self) -> None:
if self.descriptor is None:
raise OSError(f"Pinned {self.label} is closed")
def assert_path_stable(self, operation: str = "transaction") -> None:
"""Require the visible path to still name the pinned directory."""
self._require_open()
assert self.descriptor is not None
metadata = os.fstat(self.descriptor)
if (
not stat.S_ISDIR(metadata.st_mode)
or (metadata.st_dev, metadata.st_ino)
!= (self.snapshot.device, self.snapshot.inode)
):
raise OSError(f"Pinned {self.label} changed during {operation}")
if not self.path_bound:
return
current = read_physical_directory(self.path, self.label)
if current != self.snapshot:
raise OSError(
f"{self.label} changed during {operation}: {self.path}"
)
def chmod_descriptor(self, descriptor: int, mode: int) -> None:
"""Apply a mode while this directory remains pinned."""
self._require_open()
chmod_open_file(descriptor, mode)
def name_for(self, file_path: str) -> str:
absolute = os.path.abspath(file_path)
if os.path.normcase(os.path.dirname(absolute)) != os.path.normcase(self.path):
raise ValueError(f"File is outside pinned {self.label}: {file_path}")
name = os.path.basename(absolute)
if not name or name in {".", ".."}:
raise ValueError(f"Invalid file name in pinned {self.label}: {file_path}")
return name
def path_for(self, name: str) -> str:
if not name or name in {".", ".."} or os.path.basename(name) != name:
raise ValueError(f"Invalid file name in pinned {self.label}: {name}")
return os.path.join(self.path, name)
def list_names(self) -> list[str]:
"""List direct entries while retaining the physical directory handle."""
self._require_open()
self.assert_path_stable("directory enumeration")
try:
if os.name == "nt":
names = os.listdir(self.path)
else:
assert self.descriptor is not None
names = os.listdir(self.descriptor)
except OSError as error:
raise OSError(f"List {self.label} at {self.path}: {error}") from error
self.assert_path_stable("directory enumeration")
return sorted(names)
def open_file(self, name: str, flags: int, mode: int = 0o600) -> int:
self._require_open()
if os.name == "nt":
return os.open(self.path_for(name), flags, mode)
assert self.descriptor is not None
return os.open(name, flags, mode, dir_fd=self.descriptor)
def stat_file(self, name: str) -> os.stat_result:
self._require_open()
if os.name == "nt":
return os.lstat(self.path_for(name))
assert self.descriptor is not None
return os.stat(name, dir_fd=self.descriptor, follow_symlinks=False)
def remove_file(self, name: str) -> None:
self._require_open()
if os.name == "nt":
os.remove(self.path_for(name))
return
assert self.descriptor is not None
os.unlink(name, dir_fd=self.descriptor)
def replace_file(self, source_name: str, destination_name: str) -> None:
self._require_open()
if os.name == "nt":
os.replace(self.path_for(source_name), self.path_for(destination_name))
return
assert self.descriptor is not None
os.replace(
source_name,
destination_name,
src_dir_fd=self.descriptor,
dst_dir_fd=self.descriptor,
)
def sync(self) -> None:
"""Persist directory entries where the host exposes directory fsync."""
self._require_open()
if os.name == "nt":
# Windows directory handles do not support FlushFileBuffers.
return
if os.name != "posix":
raise OSError(f"Unsupported transaction platform: {os.name}")
assert self.descriptor is not None
os.fsync(self.descriptor)
def link_file(self, source_name: str, destination_name: str) -> None:
"""Create a no-clobber hard link within the pinned directory."""
self._require_open()
if os.name == "nt":
os.link(self.path_for(source_name), self.path_for(destination_name))
return
assert self.descriptor is not None
os.link(
source_name,
destination_name,
src_dir_fd=self.descriptor,
dst_dir_fd=self.descriptor,
follow_symlinks=False,
)
def read_file(
self,
name: str,
label: str,
maximum_bytes: int,
) -> Optional[FileSnapshot]:
file_path = self.path_for(name)
try:
before = self.stat_file(name)
except FileNotFoundError:
return None
except OSError as error:
raise OSError(f"Inspect {label} at {file_path}: {error}") from error
if not stat.S_ISREG(before.st_mode) or stat.S_ISLNK(before.st_mode):
raise OSError(f"{label} path is not a physical file: {file_path}")
return read_file_snapshot(
before,
lambda flags: self.open_file(name, flags),
file_path,
label,
maximum_bytes,
)
def chmod_file(
self,
name: str,
mode: int,
expected_identity: Tuple[int, int],
) -> None:
flags = os.O_RDWR | getattr(os, "O_BINARY", 0) | getattr(os, "O_CLOEXEC", 0)
flags |= getattr(os, "O_NOFOLLOW", 0)
descriptor = -1
try:
descriptor = self.open_file(name, flags)
metadata = os.fstat(descriptor)
if (
not stat.S_ISREG(metadata.st_mode)
or (metadata.st_dev, metadata.st_ino) != expected_identity
):
raise OSError(f"File changed before chmod: {self.path_for(name)}")
chmod_open_file(descriptor, mode)
os.fsync(descriptor)
finally:
if descriptor >= 0:
os.close(descriptor)