2017-01-14 9 views
0

Ich bin ein unerfahrener Linux-Programmierer und versuche zu lernen, readlink() basierend auf dieser question and answer zu verwenden.readlink sets errno zu ENOENT

Mein Aufruf an readlink() gibt -1 zurück und setzt errno zu 2 (ENOENT).

Der Code:

#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <errno.h> 
#include <iostream> 
#include <algorithm> 
#include <cstdio> 

int main(int argc, char* argv[]) 
{ 
    char szTmp[100]; 
    snprintf(szTmp, 100, "proc/%d/exe", getpid()); 
    std::cout << "szTmp is " << szTmp << std::endl; 
    char executingFolder[500]; 
    errno = 0; 
    int bytes = std::min(readlink(szTmp, executingFolder, 500), (ssize_t)499); 

    if (bytes > 0) 
    { 
    executingFolder[bytes] = '\0'; 
    } 

    std::cout << "bytes is " << bytes << std::endl; 
    std::cout << "errno is " << errno; 
    if (ENOENT == errno) 
    { 
    std::cout << " ENOENT"; 
    } 
    std::cout << std::endl; 
    std::cout << "Executing folder is \"" << executingFolder << "\"" << std::endl; 

    return 0; 
} 

Der Ausgang:

(Ein Beispiel von einer Iteration seit pid Änderungen)

szTmp is proc/22272/exe 
bytes is -1 
errno is 2 ENOENT 
Executing folder is "" 

Dinge, die ich versucht habe:

  • Nach der Kompilierung: sudo ./a.out (denken, dass der Verzeichniszugriff wegen fehlender Erlaubnis eingeschränkt wurde). Ergebnis: Unverändertes Verhalten von ./a.out
  • SIGINT das Programm während der Ausführung und verifiziert, dass /proc/<pid>/exe existiert. Ergebnis: Es existiert konsistent für jeden Lauf des Programms.
  • Überprüft, dass der Wert der Zielverbindung innerhalb von 499 Zeichen liegt.

Kann jemand bitte helfen, das Problem zu identifizieren? Nachdem ich die readlink Manpage und Online-Beschreibungen gelesen habe, und den notierten StackOverflow-Artikel, bin ich immer noch unklar, was falsch ist.

Vielen Dank.

Antwort

3

proc/1234/exe ist ein relativer Pfad.

Ich denke, Sie wollen /proc/%d/exe, die ein absoluter Pfad ist, und bezieht sich korrekt auf die /proc Verzeichnis.


Zweitens, weil readlink() wird das Ergebnis im Fall gestutzt die Puffer zu klein sind, sollten Sie den Fall betrachten, wo der Rückgabewert == bufsiz ist ein Fehler zu sein, da Abschneiden geschehen kann. Du kannst es nicht wissen.


Auch "Executing Ordner" ist nicht das, was /proc/<pid>/exe gibt Ihnen. /proc/<pid>/exe ist ein Symlink zur aktuell laufenden ausführbaren Datei (Datei), kein Verzeichnis.

+0

Ich habe dich dazu geschlagen! –

+0

Danke, ich verstehe deine Erklärung und meinen Fehler jetzt. – StoneThrow

+1

@KeithThompson Sie haben tatsächlich, um etwa 30 Sekunden, aber ich musste die anderen zwei Fehler aufbringen. –

1

proc/22272/exe ist ein relativer Pfadname. Es löst in die Datei exe, im Verzeichnis 22272, im Verzeichnis proc, in Ihrem aktuellen Verzeichnis. Sofern Ihr aktuelles Verzeichnis nicht / ist, ist das unwahrscheinlich.

Sie mögen ein absoluten Pfadnamen, mit / starten, in diesem Fall /proc/22272/exe.

ändern diese:

snprintf(szTmp, 100, "proc/%d/exe", getpid()); 

dazu:

snprintf(szTmp, 100, "/proc/%d/exe", getpid()); 

Aber bevor Sie Ihr Programm zu beheben, können Sie versuchen, diese:

(cd/; ~/a.out) 

(a.out vorausgesetzt, in Ihrem Haus Verzeichnis).

+0

Vielen Dank auch. Ich hasse es, zwischen zwei richtigen und großzügigen Antworten aus derselben Minute zu wählen (SO gibt nur eine winzige Auflösung (?)). Aber ich werde beide Antworten aufwerten. – StoneThrow

Verwandte Themen