BEZEICHNUNG¶
getdents - Verzeichniseinträge ermitteln
ÜBERSICHT¶
int getdents(unsigned int fd, struct linux_dirent *dirp,
unsigned int count);
Anmerkung: 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 Blockgerät
- DT_CHR
- Dies ist ein Zeichengerät
- DT_DIR
- Dies ist ein Verzeichnis
- DT_FIFO
- Dies ist eine Pipeline mit Namen (FIFO)
- 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 bieten nur einige Dateisysteme (darunter: Btrfs, Ext2, Ext3 und Ext4)
volle Unterstützung für die Rückgabe des Dateityps in
d_type. Alle Anwendungen müssen korrekt mit der Rückgabe von
DT_UNKNOWN umgehen.
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
- Ungültiger Dateideskriptor fd
- EFAULT
- Das Argument zeigt aus dem Adressraum des aufrufenden
Prozesses heraus.
- EINVAL
- Ergebnispuffer ist zu klein
- ENOENT
- Kein solches Verzeichnis.
- ENOTDIR
- Der Deskriptor bezieht sich nicht auf ein Verzeichnis
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¶
Diese Seite ist Teil der Veröffentlichung 3.42 des Projekts Linux-
man-pages. Eine Beschreibung des Projekts und Informationen, wie Fehler
gemeldet werden können, finden sich unter
http://www.kernel.org/doc/man-pages/.
ÜBERSETZUNG¶
Die deutsche Übersetzung dieser Handbuchseite wurde von Helge Kreutzmann
<debian@helgefjell.de> und Martin Eberhard Schauer
<Martin.E.Schauer@gmx.de> 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>.