Problem mit dirent

Hallo,

manchmal muss ich aus einem C Programm heraus erkennen können (Unix/Linux/Mac OS X), welche Dateien sich in einem Verzeichnis path befinden und welchem Dateityp diese Dateien entsprechen. Dazu bediene ich mich der Funktion dirent *readdir (DIR *dirp) in Verbindung mit DIR *opendir(const char *path). Die Struktur dirent enthält neben dem Dateinamen auch noch den Dateityp codiert als u_int8_t (unsigned char):

#define DT\_UNKNOWN 0
#define DT\_FIFO 1
#define DT\_CHR 2
#define DT\_DIR 4
#define DT\_BLK 6
#define DT\_REG 8
#define DT\_LNK 10
#define DT\_SOCK 12
#define DT\_WHT 14

Nun gibt es aber Filesyteme (z.B. reiserfs unter Linux Kernel 2.6), bei denen stets DT_UNKNOWN zurückgeliefert wird. Um in diesen Fällen zu überprüfen, ob es sich z.B. um ein Verzeichnis handelt (und nicht z.B. um eine reguläre Datei), greife ich auf folgende Methode zurück: Ich versuche die Datei mittels opendir() zu öffnen und wenn dies misslingt, schließe ich aus, dass es ein Verzeichnis ist. Diese Methode ist aber nicht nur unelegant und uneffizient, sondern es ergibt sich u.a. das Problem, dass opendir() auch dann misslingt, wenn die Berechtigung fehlt, das Verzeichnis lesen zu dürfen. Um zu prüfen, ob es sich um eine reguläre Datei handelt, versuche ich, die Datei mittels ifstream::open() zu öffnen, und wenn dies misslingt usw… Auch dies ist alles andere als effizient, den Dateityp herauszufinden.

Und nun meine Frage. Gibt es neben readdir() eine weitere Möglichkeit, den Inhalt eines Verzeichnisses einschließlich Dateitypen zu lesen? (Vorzugsweise eine Möglichkeit, die möglichst portabel ist, sich möglichst an Standards hält.)

Viele Grüße,
Jens

PS: Hier ein Beispielcode:

#include 
#include 

using std::cout;
using std::endl;

int main(int argc, char \*argv[] )
{
 DIR \*dirp=0;

 if ( argc d\_type d\_name 

dirent->d_type kenne ich gar nicht, ich würde vermuten, dass dieses Element nicht auf allen Systemen vorhanden ist. Aber readdir() ist schon ok. Überlicherweise macht man auf die gelesenen Einträge lstat()

 struct stat buf;
 if (lstat(completeFileName, &buf) == 0)
 {
 if ( (buf.st\_mode & S\_IFDIR) )
 {
 // Verzeichnis
 }
 }

Hallo Markus,

Überlicherweise macht man auf die gelesenen Einträge lstat()

Diese Information ist sehr hilfreich. Vielen Dank!

Jens

PS: Mich wundert, dass in den man-pages von readdir bzw. dirent kein Verweis auf lstat existiert.