GNU/Linux >> Znalost Linux >  >> Linux

Načíst název souboru z deskriptoru souboru v C

Měl jsem tento problém na Mac OS X. Nemáme /proc virtuální souborový systém, takže přijaté řešení nemůže fungovat.

Místo toho máme F_GETPATH příkaz pro fcntl :

 F_GETPATH          Get the path of the file descriptor Fildes.  The argu-
                    ment must be a buffer of size MAXPATHLEN or greater.

Chcete-li tedy získat soubor přidružený k deskriptoru souboru, můžete použít tento úryvek:

#include <sys/syslimits.h>
#include <fcntl.h>

char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
    // do something with the file path
}

Protože si nikdy nepamatuji, kde je MAXPATHLEN je definováno, myslel jsem PATH_MAX ze syslimits by bylo v pořádku.


Můžete použít readlink na /proc/self/fd/NNN kde NNN je deskriptor souboru. Získáte tak název souboru, jaký byl, když byl otevřen – pokud však byl soubor od té doby přesunut nebo smazán, nemusí být již přesný (ačkoli Linux může v některých případech sledovat přejmenování). Pro ověření stat zadaný název souboru a fstat fd, který máte, a ujistěte se, že st_dev a st_ino jsou stejné.

Samozřejmě, že ne všechny deskriptory souborů odkazují na soubory a u těch uvidíte nějaké zvláštní textové řetězce, například pipe:[1538488] . Protože všechny skutečné názvy souborů budou absolutní cesty, můžete snadno určit, které z nich jsou. Dále, jak poznamenali jiní, soubory mohou mít více pevných odkazů, které na ně odkazují – toto bude hlásit pouze ten, se kterým byl otevřen. Pokud chcete najít všechna jména pro daný soubor, budete muset projít celý souborový systém.


Jak zdůrazňuje Tyler, neexistuje způsob, jak udělat to, co požadujete „přímo a spolehlivě“, protože daný FD může odpovídat 0 názvům souborů (v různých případech) nebo> 1 (více „pevných odkazů“ je obecně popsána druhá situace. ). Pokud stále potřebujete funkcionalitu se všemi omezeními (na rychlost A na možnost získat výsledky 0, 2, ... místo 1), můžete to udělat následovně:nejprve fstat FD -- to vám řekne , ve výsledném struct stat , na jakém zařízení soubor žije, kolik pevných odkazů má, zda se jedná o speciální soubor atd. To již může odpovídat na vaši otázku -- např. pokud 0 pevných odkazů, budete VĚDĚT, že na disku ve skutečnosti není žádný odpovídající název souboru.

Pokud vám statistiky dávají naději, musíte „chodit po stromě“ adresářů na příslušném zařízení, dokud nenajdete všechny pevné odkazy (nebo jen první, pokud jich nepotřebujete více a bude stačit kterýkoli ). Pro tento účel používáte readdir (a opendir &c samozřejmě) rekurzivně otevírající podadresáře, dokud nenajdete v struct dirent tedy obdržel stejné číslo inodu, jaké jste měli v původním struct stat (v tomto okamžiku, pokud chcete celou cestu, spíše než jen název, budete muset projít řetězec adresářů pozpátku, abyste jej rekonstruovali).

Pokud je tento obecný přístup přijatelný, ale potřebujete podrobnější kód C, dejte nám vědět, nebude těžké ho napsat (i když ho raději nebudu psát, pokud je k ničemu, tj. nemůžete odolat nevyhnutelně pomalému výkonu nebo možnost získat !=1 výsledek pro účely vaší aplikace;-).


Ve Windows pomocí GetFileInformationByHandleEx, předáním FileNameInfo, můžete získat název souboru.


Linux
  1. Přenositelnost odkazů na deskriptor souboru?

  2. Čtení Grepových vzorů ze souboru?

  3. Čtení ze souboru v sestavě

  1. Přidání časového razítka k názvu souboru s mv v BASH

  2. Jak vytvořit soubor v Linuxu z okna terminálu?

  3. Je možné použít / v názvu souboru?

  1. Jak extrahovat soubor filename.tar.gz

  2. Vytvořte PEM ze souboru PPK

  3. Jak se install -c liší od cp