GETDENTS(2)

BEZEICHNUNG
getdents - Verzeichniseinträge ermitteln

ÜBERSICHT
int getdents(unsigned int fd, struct linux_dirent *dirp,
             unsigned int count);
Hinweis: Es gibt keinen Glibc-Wrapper für diesen Systemaufruf; siehe ANMERKUNGEN.

BESCHREIBUNG
Dies ist nicht die Funktion, an der Sie interessiert sind. Lesen Sie readdir(3) für die POSIX-konforme C-Bibliotheksschnittstelle. Diese Seite dokumentiert die nackte Kernel-Systemaufruf-Schnittstelle.

Der Systemaufruf getdents() liest mehrere linux_dirent-Strukturen aus dem Verzeichnis, auf das der offene Dateideskriptor fd verweist, in den Puffer, auf den dirp zeigt. Das Argument count spezifiziert die Größe dieses Puffers.

Die Struktur linux_dirent ist wie folgt deklariert:

struct linux_dirent {
    unsigned long  d_ino;     /* Inode-Nummer */
    unsigned long  d_off;     /* Offset zum nächsten linux_dirent */
    unsigned short d_reclen;  /* Länge dieses linux_dirent */
    char           d_name[];  /* Dateiname (abgeschlossen mit */
                              /* Null-Byte */
                        /* Tatsächlich ist die Länge (d_reclen - 2 -
                           offsetof(struct linux_dirent, d_name)) */
    /*
    char           pad;       // Null-Byte zum Auffüllen
    char           d_type;    // Dateityp (nur seit Linux 2.6.4);
                              // Offset beträgt (d_reclen - 1)
    */
}

d_ino ist eine Inode-Nummer. d_off ist der Abstand zwischen dem Anfang des Verzeichnisses und dem Anfang des nächsten linux_dirent. d_reclen ist die Größe dieses gesamten linux_dirent. d_name ist ein nullterminierter Dateiname. d_type ist ein Byte am Ende der Struktur, das den Dateityp anzeigt. Es enthält einen der folgenden Werte (definiert in <dirent.h>):

DT_BLK
    Dies ist ein blockorientiertes Gerät.

DT_CHR
    Dies ist ein zeichenorientiertes Gerät.

DT_DIR
    Dies ist ein Verzeichnis.

DT_FIFO
    Dies ist ein FIFO (eine benannte Pipe).

DT_LNK
    Dies ist ein symbolischer Link.

DT_REG
    Dies ist eine reguläre Datei.

DT_SOCK
    Dies ist ein UNIX Domain Socket.

DT_UNKNOWN
    Der Dateityp ist unbekannt.

Das d_type-Feld wird seit Linux 2.6.4 implementiert. Es nimmt den Raum ein, der zuvor ein auf Null gesetztes Füllbyte in der linux_dirent-Struktur war. So ergibt mit Kerneln vor 2.6.3 ein versuchter Zugriff auf dieses Feld immer den Wert 0 (DT_UNKNOWN).

Derzeit unterstützen nur ein paar Dateisysteme (darunter Btrfs, ext2, ext3 und ext4) die Rückgabe des Dateityps in d_type vollständig. Alle Anwendungen müssen mit dem Rückgabewert DT_UNKNOWN umgehen können.

RÜCKGABEWERT
Bei Erfolg wird die Anzahl der gelesenen Bytes zurückgeliefert. Am Verzeichnisende wird 0 zurückgeliefert. Im Fehlerfall wird -1 zurückgeliefert und errno entsprechend gesetzt.

FEHLER

EBADF
    Unzulässiger Dateideskriptor fd.

EFAULT
    Das Argument zeigt aus dem Adressraum des aufrufenden Prozesses heraus.

EINVAL
    Ergebnispuffer ist zu klein.

ENOENT
    Kein solches Verzeichnis.

ENOTDIR
    Dateideskriptor zeigt nicht auf ein Verzeichnis.

KONFORM ZU
SVr4.

ANMERKUNGEN
Glibc stellt keinen Wrapper für diesen Systemaufruf bereit, rufen Sie ihn mit syscall(2) auf. Sie müssen die linux_dirent-Struktur selbst definieren. Allerdings möchten Sie wahrscheinlich stattdessen readdir(3) verwenden. Dieser Aufruf ersetzt readdir(2). Der ursprüngliche Linux-Systemaufuf getdents() konnte nicht mit großen Dateisystemen und großen Dateioffsets umgehen. Folglich wurde in Linux 2.4 getdents64() hinzugefügt, mit »breiteren« Typen für die Felder d_ino und d_off in der linux_dirent-Struktur.

BEISPIEL
Das nachfolgende Programm zeigt die Verwendung von getdents(). Die folgende Ausgabe zeigt ein Beispiel davon, was bei der Ausführung des Programms auf einem Ext2-Verzeichnis gesehen werden kann.
$ ./a.out /testfs/
--------------- nread=120 ---------------
i-node#  file type  d_reclen  d_off   d_name
       2  directory    16         12  .
       2  directory    16         24  ..
      11  directory    24         44  lost+found
      12  regular      16         56  a
  228929  directory    16         68  sub
   16353  directory    16         80  sub2
  130817  directory    16       4096  sub3

  Programmquelltext
#define _GNU_SOURCE
#include <dirent.h>     /* Definiert DT_*-Konstanten */
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)
struct linux_dirent {
    long           d_ino;
    off_t          d_off;
    unsigned short d_reclen;
    char           d_name[];
};
#define BUF_SIZE 1024
int
main(int argc, char *argv[])
{
    int fd, nread;
    char buf[BUF_SIZE];
    struct linux_dirent *d;
    int bpos;
    char d_type;
    fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
    if (fd == -1)
        handle_error("open");
    for ( ; ; ) {
        nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
        if (nread == -1)
            handle_error("getdents");
        if (nread == 0)
            break;
        printf("--------------- nread=%d ---------------\n", nread);
        printf("i-node#  file type  d_reclen  d_off   d_name\n");
        for (bpos = 0; bpos < nread;) {
            d = (struct linux_dirent *) (buf + bpos);
            printf("%8ld  ", d->d_ino);
            d_type = *(buf + bpos + d->d_reclen - 1);
            printf("%-10s ", (d_type == DT_REG) ?  "regular" :
                             (d_type == DT_DIR) ?  "directory" :
                             (d_type == DT_FIFO) ? "FIFO" :
                             (d_type == DT_SOCK) ? "socket" :
                             (d_type == DT_LNK) ?  "symlink" :
                             (d_type == DT_BLK) ?  "block dev" :
                             (d_type == DT_CHR) ?  "char dev" : "???");
            printf("%4d %10lld  %s\n", d->d_reclen,
                    (long long) d->d_off, d->d_name);
            bpos += d->d_reclen;
        }
    }
    exit(EXIT_SUCCESS);
}

SIEHE AUCH
readdir(2), readdir(3)

KOLOPHON
This page is part of release 3.70 of the Linux man-pages project. A description of the project, information about reporting bugs, and the latest version of this page, can be found at http://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Helge Kreutzmann <debian@helgefjell.de>, Martin Eberhard Schauer <Martin.E.Schauer@gmx.de> und Mario Blättermann <mario.blaettermann@gmail.com> erstellt. Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen. Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an <debian-l10n-german@lists.debian.org>.