links.c
#include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <dirent.h> #include <errno.h> static void die(const char *msg) { perror(msg); exit(EXIT_FAILURE); } int main(void) { char *dirname = "."; // . = aktuelles Verzeichnis // Verzeichnis öffnen DIR *dir = opendir(dirname); if (!dir) { die(dirname); } // Die errno wird vor jedem readdir-Aufruf auf 0 gesetzt. // Dann wird readdir aufgerufen und das Ergebnis in d // geschrieben. Die Klammern um diese Zuweisung führen // dazu, dass das Ziel der Zuweisung (also "d") als // Schleifenbedingung geprüft wird. // Eine Alternative zu dieser Schreibweise ist am Ende // des Codes, siehe (*). struct dirent *d; while (errno = 0, (d = readdir(dir))) { // Informationen über die Datei mit lstat erhalten struct stat sb; if (lstat(d->d_name, &sb)) { perror(d->d_name); // Je nach Zielstellung kann man sich hier überlegen, // ob man das Programm komplett abbrechen möchte. continue; } // Daten aus dem "sb"-struct auswerten und prüfen, ob // die Datei ein Symlink ist. Falls nicht, bei der // nächsten Datei weitermachen. if (!S_ISLNK(sb.st_mode)) { continue; } // Wenn wir hier angekommen sind, ist die Datei ein Symlink. printf("%s\n", d->d_name); } // Hier kommen wir nach der Schleife hin, also wenn d == NULL. // Wenn hier die errno != 0 ist, dann wissen wir sicher, dass // readdir den Fehler geworfen hat. if (errno) { die(dirname); } // Verzeichnis schließen closedir(dir); } /* (*) Statt der kompakten Schreibweise bei der while-Schleife könnte man das auch so schreiben: while (1) { errno = 0; struct dirent *d = readdir(dir); if (!d) { break; } ... } Funktioniert auch, ist aber wesentlich mehr Schreibarbeit. :D */