Czy można uzyskać nazwę pliku deskryptora pliku (Linux) w C?
c
linux
file
file-descriptor
adk
źródło
źródło
Odpowiedzi:
Można używać
readlink
na/proc/self/fd/NNN
gdzie NNN jest deskryptor pliku. W ten sposób otrzymasz nazwę pliku taką, jaka była w momencie otwarcia - jednak jeśli plik został przeniesiony lub usunięty od tego czasu, może już nie być dokładny (chociaż w niektórych przypadkach Linux może śledzić zmiany nazw). Aby zweryfikować,stat
nazwa pliku podana ifstat
FD masz, i upewnić się,st_dev
ist_ino
są takie same.Oczywiście nie wszystkie deskryptory plików odnoszą się do plików, a dla nich zobaczysz dziwne ciągi tekstowe, takie jak
pipe:[1538488]
. Ponieważ wszystkie prawdziwe nazwy plików będą ścieżkami bezwzględnymi, możesz łatwo określić, które z nich są wystarczające. Ponadto, jak zauważyli inni, pliki mogą mieć wiele twardych linków wskazujących na nie - spowoduje to tylko zgłoszenie tego, za pomocą którego zostały otwarte. Jeśli chcesz znaleźć wszystkie nazwy dla danego pliku, musisz po prostu przejść przez cały system plików.źródło
fd
byłoby takim odniesieniem), numeru i-węzła nie można ponownie wykorzystać. Każde oprogramowanie korzystające z numeru i-węzła po zamknięciu pliku lub przed jego otwarciem podlega z natury warunkom wyścigu.setuid()
sztuczki,/proc/self/fd
proces może nie być dostępny. Zobacz: permalink.gmane.org/gmane.linux.kernel/1302546Miałem ten problem na Mac OS X. Nie mamy
/proc
wirtualnego systemu plików, więc przyjęte rozwiązanie nie działa.Zamiast tego mamy
F_GETPATH
poleceniefcntl
:Aby pobrać plik powiązany z deskryptorem pliku, możesz użyć tego fragmentu:
Ponieważ nigdy nie pamiętam, gdzie
MAXPATHLEN
jest zdefiniowane, pomyślałem, żePATH_MAX
z syslimits będzie dobrze.źródło
getsockname
.W systemie Windows za pomocą GetFileInformationByHandleEx , przekazując FileNameInfo , możesz pobrać nazwę pliku.
źródło
Jak podkreśla Tyler, nie ma sposobu, aby zrobić to, czego potrzebujesz "bezpośrednio i niezawodnie", ponieważ dana FD może odpowiadać 0 nazwom plików (w różnych przypadkach) lub> 1 (wiele "twardych linków" jest ogólnie opisywana tą drugą sytuacją ). Jeśli nadal potrzebujesz funkcji ze wszystkimi ograniczeniami (dotyczącymi prędkości ORAZ możliwości uzyskania 0, 2, ... wyników zamiast 1), oto jak możesz to zrobić: po pierwsze, fstat FD - to ci mówi , w rezultacie
struct stat
, na jakim urządzeniu znajduje się plik, ile ma twardych linków, czy jest to plik specjalny itp. To może już odpowiedzieć na twoje pytanie - np. jeśli 0 twardych linków WIESZ, że w rzeczywistości nie ma odpowiedniej nazwy pliku na dysku.Jeśli statystyki dają ci nadzieję, musisz "chodzić po drzewie" katalogów na odpowiednim urządzeniu, aż znajdziesz wszystkie twarde linki (lub tylko pierwszy, jeśli nie potrzebujesz więcej niż jednego i każdy to zrobi ). W tym celu używasz readdir (i oczywiście opendir & c) rekurencyjnie otwierających podkatalogi, dopóki nie znajdziesz w
struct dirent
otrzymanym w ten sposób tym samym numerze i-węzła, który miałeś w oryginalestruct stat
(w tym czasie, jeśli chcesz całą ścieżkę, a nie tylko nazwę, aby odtworzyć łańcuch katalogów, musisz przejść wstecz).Jeśli to ogólne podejście jest do zaakceptowania, ale potrzebujesz bardziej szczegółowego kodu w C, daj nam znać, nie będzie to trudne do napisania (chociaż wolałbym nie pisać, jeśli jest bezużyteczne, tj. Nie możesz wytrzymać nieuchronnie powolnej wydajności lub możliwość uzyskania! = 1 wyniku na potrzeby Twojej aplikacji ;-).
źródło
Zanim uznasz to za niemożliwe, proponuję przyjrzeć się kodowi źródłowemu polecenia lsof .
Mogą istnieć ograniczenia, ale wydaje się, że lsof jest w stanie określić deskryptor pliku i nazwę pliku. Ta informacja istnieje w systemie plików / proc, więc powinno być możliwe uzyskanie do niej dostępu z twojego programu.
źródło
Możesz użyć fstat (), aby uzyskać i-węzeł pliku przez statct stat. Następnie za pomocą readdir () możesz porównać znaleziony i-węzeł z tymi, które istnieją (struct dirent) w katalogu (zakładając, że znasz katalog, w przeciwnym razie będziesz musiał przeszukać cały system plików) i znaleźć odpowiadającą mu nazwę pliku. Paskudny?
źródło
Niemożliwy. Deskryptor pliku może mieć wiele nazw w systemie plików lub może nie mieć żadnej nazwy.
Edycja: Zakładając, że mówisz o zwykłym starym systemie POSIX, bez żadnych interfejsów API specyficznych dla systemu operacyjnego, ponieważ nie określiłeś systemu operacyjnego.
źródło