GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So implementieren Sie readlink, um den Pfad zu finden

Akzeptierte Antwort ist fast richtig, außer dass Sie sich nicht auf PATH_MAX verlassen können, weil es

ist

wird nicht garantiert per POSIX definiert, wenn das System keine solche Grenze hat.

(Von der Readlink(2)-Manpage)

Wenn es definiert ist, stellt es auch nicht immer die "wahre" Grenze dar. (Siehe http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )

Die Manpage des Readlinks bietet auch eine Möglichkeit, dies auf Symlink zu tun:

Die Verwendung eines Puffers mit statischer Größe bietet möglicherweise nicht genügend Platz für den Inhalt des symbolischen Links. Die erforderliche Größe für den Puffer kann aus dem Wert stat.st_size ermittelt werden, der durch einen Aufruf von lstat(2) auf dem Link zurückgegeben wird. Allerdings sollte die Anzahl der von readlink() und read-linkat() geschriebenen Bytes überprüft werden, um sicherzustellen, dass die Größe des symbolischen Links zwischen den Aufrufen nicht zugenommen hat.

Im Fall von /proc/self/exe/ wäre stat.st_size jedoch wie bei den meisten /proc-Dateien 0. Die einzige verbleibende Lösung, die ich sehe, besteht darin, die Größe des Puffers zu ändern, während er nicht passt.

Ich schlage die Verwendung von vector<char> vor wie folgt zu diesem Zweck:

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 "";
}

Verwenden Sie die readlink()-Funktion richtig für die korrekte Verwendung von readlink Funktion.

Wenn Sie Ihren Pfad in einem std::string haben , könnten Sie so etwas tun:

#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 */
}

Wenn Sie nur nach einem festen Pfad suchen:

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 */
}

So verwenden Sie es:

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

Schauen wir uns an, was die Manpage sagt:

 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. Sollte einfach genug sein. Angesichts Ihres Puffers von 1024 Zeichen:

 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. Wie finde ich den Speicherort der ausführbaren Datei in C?

  2. Wie finde ich den Besitzer einer Datei oder eines Verzeichnisses in Python?

  3. Wie finde ich die maximale Stapelgröße?

  4. Wie man die Ergebnisse von 'find' unter Linux an mv weiterleitet

  5. Wie finde ich den Pfad HADOOP_HOME unter Linux?

So finden Sie die Portnummer eines Dienstes in Linux

So finden Sie die IP-Adresse einer virtuellen KVM-Maschine

So ermitteln Sie die Gesamtgröße eines Verzeichnisses in Linux

So finden Sie Dateien mit dem fd-Befehl in Linux

So finden Sie die Liste der installierten Repositories in Linux

So richten Sie den JAVA_HOME-Pfad in Debian 11 ein