GNU/Linux >> Znalost Linux >  >> Linux

Jak implementovat readlink k nalezení cesty

Přijatá odpověď je téměř správná, kromě toho, že se nemůžete spolehnout na PATH_MAX, protože je

není zaručeno, že bude definován podle POSIX, pokud systém takový limit nemá.

(Z manuálové stránky readlink(2))

Také, když je definován, ne vždy představuje "skutečný" limit. (Viz http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )

Manuálová stránka readlinku také poskytuje způsob, jak to udělat na symbolickém odkazu:

Použití vyrovnávací paměti statické velikosti nemusí poskytnout dostatek místa pro obsah symbolického odkazu. Požadovanou velikost vyrovnávací paměti lze získat z hodnoty stat.st_size vrácené voláním lstat(2) na odkazu. Je však třeba zkontrolovat počet bajtů zapsaných funkcemi readlink() a read‐linkat(), abyste se ujistili, že se velikost symbolického odkazu mezi voláními nezvětšila.

Nicméně v případě /proc/self/exe/ jako u většiny souborů /proc by stat.st_size byla 0. Jediné řešení, které vidím, je změnit velikost vyrovnávací paměti, dokud se nevejde.

Doporučuji použít vector<char> pro tento účel:

std::string get_selfpath()
{
    std::vector<char> buf(400);
    ssize_t len;

    do
    {
        buf.resize(buf.size() + 100);
        len = ::readlink("/proc/self/exe", &(buf[0]), buf.size());
    } while (buf.size() == len);

    if (len > 0)
    {
        buf[len] = '\0';
        return (std::string(&(buf[0])));
    }
    /* handle error */
    return "";
}

Toto Používejte správně funkci readlink() pro správné použití readlink funkce.

Pokud máte cestu v std::string , můžete udělat něco takového:

#include <unistd.h>
#include <limits.h>

std::string do_readlink(std::string const& path) {
    char buff[PATH_MAX];
    ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1);
    if (len != -1) {
      buff[len] = '\0';
      return std::string(buff);
    }
    /* handle error condition */
}

Pokud hledáte pouze pevnou cestu:

std::string get_selfpath() {
    char buff[PATH_MAX];
    ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
    if (len != -1) {
      buff[len] = '\0';
      return std::string(buff);
    }
    /* handle error condition */
}

Chcete-li jej použít:

int main()
{
  std::string selfpath = get_selfpath();
  std::cout << selfpath << std::endl;
  return 0;
}

Podívejme se, co říká manuálová stránka:

 readlink() places the contents of the symbolic link path in the buffer
 buf, which has size bufsiz.  readlink does not append a NUL character to
 buf.

OK. Mělo by to být dostatečně jednoduché. Vzhledem k vaší vyrovnávací paměti 1024 znaků:

 char buf[1024];

 /* The manpage says it won't null terminate.  Let's zero the buffer. */
 memset(buf, 0, sizeof(buf));

 /* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
 if (readlink("/proc/self/exe", buf, sizeof(buf)-1) < 0)
 {
    /* There was an error...  Perhaps the path does not exist
     * or the buffer is not big enough.  errno has the details. */
    perror("readlink");
    return -1;
 }

Linux
  1. Jak auditovat oprávnění pomocí příkazu find

  2. Jak přenést výsledky 'najít' do mv v Linuxu

  3. Jak najít instalační cestu git v Mac nebo Linuxu?

  1. Jak zjistit, zda je disk SSD nebo HDD v Linuxu

  2. Najděte adresu URL souboru

  3. Jak najít výchozího správce souborů?

  1. Jak používat Linuxový příkaz find k hledání souborů

  2. Jak najdu umístění spustitelného souboru v C?

  3. jak najít vlastníka souboru nebo adresáře v pythonu