Created
June 15, 2021 11:18
-
-
Save gicmo/bce9024dae3efea89c713fe13ff8fc2f to your computer and use it in GitHub Desktop.
path fd resolution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import contextlib | |
import os | |
def find_entry(dir_fd: int, target) -> os.DirEntry: | |
with os.scandir(dir_fd) as it: | |
for entry in it: | |
info = entry.stat(follow_symlinks=False) | |
if os.path.samestat(target, info): | |
return entry | |
return None | |
@contextlib.contextmanager | |
def close_fd_on_error(fd: int): | |
try: | |
yield | |
except: | |
os.close(fd) | |
raise | |
def path_for_fd(target: int) -> str: | |
flags = os.O_RDONLY | os.O_CLOEXEC | os.O_NOFOLLOW | os.O_DIRECTORY | |
root_info = os.stat("/") | |
parent = os.open("..", flags, dir_fd=target) | |
result = [] | |
while True: | |
with close_fd_on_error(parent): | |
# Check if we have reached root | |
info = os.fstat(target) | |
if os.path.samestat(root_info, info): | |
break | |
entry = find_entry(parent, info) | |
if entry is None: | |
raise FileNotFoundError(f"Could not find entry {str(result)}") | |
print(entry) | |
result.append(entry.name) | |
with close_fd_on_error(parent): | |
target = parent | |
parent = os.open("..", flags, dir_fd=parent) | |
return "/" + "/".join(reversed(result)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment