2016-04-26 8 views
1

Ich drucke das Ergebnis S_ISDIR(info->st_mode) und S_ISREG(info->st_mode) über ein Verzeichnis, das dynamische Bibliothek mit .so Erweiterung enthält, und das Ergebnis ist ziemlich überraschend, S_ISREG kehrt 0 während S_ISDIR liefert 1.C seltsam stat st_mode

Ich bin ein wenig verwirrt ...

Der Code:

DIR *dir; 
if ((dir = opendir (dirname)) != NULL) { 
    struct dirent *ent; 
    while ((ent = readdir (dir)) != NULL) { 
    struct stat info; 
    stat(ent->d_name, &info); 
    printf("file: %s, S_ISREG: %d, S_ISDIR: %d", ent->d_name, S_ISREG(info.st_mode), S_ISDIR(info.st_mode)); 
    } 
} 
closedir(dir); 

Die Ausgabe sieht so aus:

file: ., S_ISREG: 0, S_ISDIR: 1 
file: zyva.so, S_ISREG: 0, S_ISDIR: 1 
file: .gitignore, S_ISREG: 1, S_ISDIR: 0 
file: .., S_ISREG: 0, S_ISDIR: 1 
file: plugin-app, S_ISREG: 0, S_ISDIR: 1 
file: chat.so, S_ISREG: 0, S_ISDIR: 1 

Plugin-App ist auch eine ausführbare Datei, so ist es auch eine normale Datei ...

+0

Sind Sie auf einem Mac? –

+0

Nein, ich bin auf Linux. –

+2

Ich denke, Ihr Code wird nur funktionieren, wenn "dirname" ist "". "'. Andernfalls müssen Sie 'dirname' und' ent-> d_name' verketten, bevor Sie 'stat' aufrufen. –

Antwort

6

Sie nicht den Rückgabewert von stat() überprüfen haben. Ich wette, wenn Sie das tun, finden Sie, dass es fehlgeschlagen ist. In diesem Fall ist struct stat nicht ausgefüllt, enthält also nur nicht initialisierten Müll (oder das Ergebnis eines vorherigen erfolgreichen Anrufs).

Warum ist es fehlgeschlagen? Ich wette, Sie finden das errno == ENOENT. Beachten Sie, dass ent->d_name enthält nur die Name der Datei, nicht die Pfad, so wenn Sie versuchen, stat es, wird es als ein Pfad relativ zum aktuellen Arbeitsverzeichnis interpretiert. Wenn dirname nicht das Verzeichnis ist, in dem Sie sich bereits befinden, suchen Sie nach diesen Dateien an der falschen Stelle stat, so dass es kein Wunder ist, dass sie nicht gefunden werden.

Entweder chdir(dirname) vor Ihrem stat s tun, oder auch den vollständigen Pfad in einem separaten Puffer konstruieren, indem dirname/ an die Dateinamen vorangestellt wird (stellen Sie sicher, dass die Längen zu überprüfen, um sicherzustellen, dass Sie nicht überrannt Ihre Puffer nicht).

+2

... oder 'fstatat' verwenden; Das ist ziemlich genau das, wofür es ist. –

+0

@ WumpusQ.Wumbley Was für ein seltsamer, aber nützlicher Anruf! Ich hatte noch nie davon gehört. Vielen Dank. (Sieht aber aus wie ein Tippfehler für 'fstat' :-)) –

+0

Noch nie davon gehört! Gibt es eine Möglichkeit, einen Dateideskriptor von einem 'DIR *' zu bekommen? Oder soll ich das Verzeichnis auch mit Standard 'open' öffnen und' fstatat' aufrufen? –