BEZEICHNUNG

getdents, getdents64 - Verzeichniseinträge ermitteln

BIBLIOTHEK

Standard-C-Bibliothek ( libc, -lc)

ÜBERSICHT

#include <sys/syscall.h>      /* Definition der SYS_*-Konstanten */
#include <unistd.h>
long syscall(SYS_getdents, unsigned int dd, struct linux_dirent *Verzz,
             unsigned int Zähler);
#define _GNU_SOURCE           /* siehe feature_test_macros(7) */
#include <dirent.h>
ssize_t getdents64(int fd, void Verzz[.Zähler], size_t Zähler);
Hinweis: Glibc stellt keinen Wrapper für getdents() bereit; rufen Sie es mittels syscall(2) auf.
Hinweis: Es gibt in Glibc keine Definition von struct linux_dirent; siehe ANMERKUNGEN.

BESCHREIBUNG

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

getdents()

Der Systemaufruf getdents() liest mehrere linux_dirent-Strukturen aus dem Verzeichnis, auf das der offene Dateideskriptor dd verweist, in den Puffer, auf den Verzz zeigt. Das Argument Zähler 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;     /* Versatz zum nächsten  linux_dirent */
    unsigned short d_reclen;  /* Länge dieses  linux_dirent */
    char           d_name[];  /* Dateiname (abgeschlossen mit */
                              /* Nullbytes) */
                        /* 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);
                              // Versatz 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 bis einschließlich Linux 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.

getdents64()

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. Zusätzlich unterstützt getdents64() ein explizites d_type-Feld.
Der getdents64()-Systemaufruf ähnelt dem von getdents(), außer dass das zweite Argument ein Zeiger auf einen Puffer ist, der Strukturen des folgenden Typs enthält:

struct linux_dirent64 {
    ino64_t        d_ino;    /* 64-bit-Inode-Nummer */
    off64_t        d_off;    /* 64-bit-Offset zur nächsten Struktur */
    unsigned short d_reclen; /* Größe dieses Verzeichniseintrags */
    unsigned char  d_type;   /* Dateityp */
    char           d_name[]; /* Dateiname (null-terminiert) */
};

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 gesetzt, um den Fehler anzuzeigen.

FEHLER

EBADF
Unzulässiger Dateideskriptor dd.
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.

STANDARDS

SVr4.

ANMERKUNGEN

Bibliotheksunterstützung für getdents64() wurde in Glibc 2.30 hinzugefügt; Glibc stellt keinen Wrapper für getdents() bereit. Der Aufruf von getdents() (oder getdents64() unter älteren Glibc-Versionen) benötigt die Verwendung von syscall(2). In diesem Fall müssen Sie die Struktur linux_dirent64 selbst definieren.
Wahrscheinlich möchten Sie readdir(3) statt einer dieser Systemaufrufe verwenden.
Diese Aufrufe ersetzen readdir(2).

BEISPIELE

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 ---------------
inode#    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 <err.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
struct linux_dirent { unsigned 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; char d_type; char buf[BUF_SIZE]; long nread; struct linux_dirent *d;
fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY); if (fd == -1) err(EXIT_FAILURE, "open");
for (;;) { nread = syscall(SYS_getdents, fd, buf, BUF_SIZE); if (nread == -1) err(EXIT_FAILURE, "getdents");
if (nread == 0) break;
printf("--------------- nread=%ld ---------------\n", nread); printf("inode# file type d_reclen d_off d_name\n"); for (size_t bpos = 0; bpos < nread;) { d = (struct linux_dirent *) (buf + bpos); printf("%8lu ", 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 %10jd %s\n", d->d_reclen, (intmax_t) d->d_off, d->d_name); bpos += d->d_reclen; } }
exit(EXIT_SUCCESS); }

SIEHE AUCH

readdir(2), readdir(3), inode(7)

ÜBERSETZUNG

Die deutsche Übersetzung dieser Handbuchseite wurde von Helge Kreutzmann <[email protected]>, Martin Eberhard Schauer <[email protected]> und Mario Blättermann <[email protected]> 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 die Mailingliste der Übersetzer

Recommended readings

Pages related to getdents you should read also: