Skip to content

Instantly share code, notes, and snippets.

@gicmo
Created June 15, 2021 11:18
Show Gist options
  • Save gicmo/bce9024dae3efea89c713fe13ff8fc2f to your computer and use it in GitHub Desktop.
Save gicmo/bce9024dae3efea89c713fe13ff8fc2f to your computer and use it in GitHub Desktop.
path fd resolution
#!/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