Verzeichnisse

Martin Kompf

Die POSIX Bibliotheken stellen einfache Funktionen für die Arbeit mit den Verzeichnissen des Dateisystems zur Verfügung.

Eine immer wieder auftretende Anforderung an C-Programme ist der Zugriff auf die Verzeichnisstruktur des Dateisystems. Insbesondere die Ermittlung und Veränderung des momentanen Arbeitsverzeichnisses sowie das Auflisten aller in einem Verzeichnis stehender Dateien sind häufig vorkommende Aufgaben.

POSIX hilft

Überraschenderweise bietet die Sprache C zumindest in ihrer im ANSI Standard definierten Ausprägung dafür keinerlei eingebaute Funktionen an. Um diesen - an und für sich unhaltbaren - Zustand zu verbessern, wurde die POSIX 1003.1 Spezifikation ins Leben gerufen. Diese Spezifikation entstand zur selben Zeit wie der ANSI C Standard und viele - aber leider nicht alle - POSIX Funktionen gibt es auch in ANSI C. Glücklicherweise existieren aber eine Reihe von POSIX kompatiblen Bibliotheken für C Compiler. Insbesondere auf den Unix Plattformen und GNU/Linux gehören diese heute zur Standardausstattung eines Entwicklungssystems.

Das nachfolgende Programm zeigt die Benutzung der POSIX Funktionen getcwd zur Abfrage des momentanen Arbeitsverzeichnisses und opendir, readdir sowie closedir zum Auslesen eines Verzeichnisses. Eine Liste aller POSIX Funktionen, die nicht in den ANSI C Standard aufgenommen wurden, findet sich hier.

#define _POSIX_SOURCE 1
#define _POSIX_ 1

#include <unistd.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>

int main()
{
  char cwd[_POSIX_PATH_MAX + 1];
  DIR *dir;
  struct dirent *ent;

  /* vollen Pfadnamen des momentanen 
   * Arbeitsverzeichnises ausgeben 
   */
  if (getcwd(cwd, _POSIX_PATH_MAX + 1)) {
    printf("*** Listing of: %s ***\n", cwd);
  }

  /* momentanes Arbeitsverzeichnis öffnen 
   */
  if ((dir = opendir(".")) == NULL) {
    perror("Unable to open directory");
    exit(1);
  }
  /* alle Einträge aus Verzeichnis lesen 
   * und ausgeben
   */
  while ((ent = readdir(dir)) != NULL) {
     printf("%s\n",ent->d_name);
  }
  /* Verzeichnis schließen */
  closedir(dir);

  return 0;
}

Dieses Programm sollte sich auf allen modernen Unix Plattformen übersetzen, linken und ausführen lassen. Getestet wurde vom Autor unter Linux und Solaris jeweils mit dem GNU Compiler.

Einschränkungen unter Windows

Unter Windows sieht die Situation leider nicht so rosig aus. Zumindest der Borland C++ Compiler ist jedoch weitgehend POSIX kompatibel. Allerdings kennt dieser den Header <unistd.h> nicht; ersetzt man diesen jedoch durch <dir.h>, dann funktioniert das Beispielprogramm wunderbar. Benutzer von Microsoft Visual C++ hingegen haben keine POSIX Kompatibiltät zu Verfügung und müssen auf die properitären File I/O Funktionen wie GetCurrentDirectoty, FindFirstFile, FindNextFile und so weiter zurückgreifen.