Provided by: manpages-pl-dev_4.28.0-2_all 

NAZWA
getdents, getdents64 - pobiera wpisy z katalogu
BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)
SKŁADNIA
#include <sys/syscall.h> /* Definicja stałych SYS_* */
#include <unistd.h>
long syscall(SYS_getdents, unsigned int fd, struct linux_dirent *dirp,
unsigned int count);
#define _GNU_SOURCE /* Zob. feature_test_macros(7) */
#include <dirent.h>
ssize_t getdents64(int fd, void dirp[.count], size_t count);
Uwaga: glibc nie udostępnia opakowania dla getdents(), co wymusza użycie syscall(2).
Note: W glibc brak definicji struct linux_dirent; zob. UWAGI.
OPIS
Nie są to interfejsy, które cię interesują. Opis implementacji interfejsu zgodnego z POSIX w bibliotece C
znajduje się w readdir(3). Niniejsza strona opisuje nagi interfejs wywołania systemowego.
getdents()
Wywołanie systemowe getdents() odczytuje kolejne struktury linux_dirent z katalogu wskazywanego przez
przez deskryptor otwartego pliku fd do bufora wskazywanego przez dirp. Argument count określa rozmiar
tego bufora.
Struktura linux_dirent jest zadeklarowana następująco:
struct linux_dirent {
unsigned long d_ino; /* Numer i-węzła */
unsigned long d_off; /* Nie jest przesunięciem; zob. niżej */
unsigned short d_reclen; /* Długość tego linux_dirent */
char d_name[]; /* Nazwa pliku (zakończ. znakiem null) */
/* długość to faktycznie (d_reclen - 2 -
offsetof(struct linux_dirent, d_name)) */
/*
char pad; // Zerowy bajt wyrównania
char d_type; // Typ pliku (tylko od Linuksa
// 2.6.4); przesunięciem jest (d_reclen - 1)
*/
}
d_ino jest numerem i-węzła. d_off jest wartością zależną od systemu plików, która nie ma znaczenia dla
przestrzeni użytkownika, choć w starszych systemach plików była odległością od początku katalogu do
początku następnej struktury linux_dirent; zob. readdir(3). d_reclen jest wielkością tej całej struktury
linux_dirent. d_name jest nazwą pliku zakończoną znakiem NUL.
d_type jest bajtem na końcu struktury wskazującym typ pliku. Zawiera jedną z następujących wartości
(zdefiniowanym w <dirent.h>):
DT_BLK Jest to urządzenie blokowe
DT_CHR Jest to urządzenie znakowe.
DT_DIR Jest to katalog.
DT_FIFO Jest to potok nazwany (FIFO).
DT_LNK Jest to dowiązanie symboliczne.
DT_REG Jest to zwykły plik.
DT_SOCK Jest to gniazdo dziedziny Uniksa.
DT_UNKNOWN Typ pliku jest nieznany.
Pole d_type zaimplementowano od Linuksa 2.6.4. Zajmuje miejsce, które wcześniej zajmował zerowy bajt
wypełnienia w strukturze linux_dirent. Z tego względu jądra do Linuksa 2.6.3, próbujące uzyskać dostęp do
tego pola zawsze zwracają wartość 0 (DT_UNKNOWN).
Obecnie jedynie niektóre systemy plików (m.in Btrfs, ext2, ext3 i ext4) obsługują w pełni zwracanie typu
pliku w d_type. Wszystkie programy muszą poprawnie obsługiwać zwrócenie wartości DT_UNKNOWN.
getdents64()
Pierwotne, linuksowe wywołanie getdents() nie obsługiwało dużych systemów plików i dużych przesunięć
pliku. Z tego powodu, Linux 2.4 dodał getdents64(), z szerszymi typami pól d_ino i d_off. Dodatkowo,
getdents64() obsługuje wprost pole d_type.
Wywołanie systemowe getdents64() zachowuje się jak getdents(), tyle że jego drugi argument jest
wskaźnikiem do bufora zawierającego strukturę następującego typu:
struct linux_dirent64 {
ino64_t d_ino; /* 64-bitowy numer i-węzła */
off64_t d_off; /* Nie jest przesunięciem, zob. getdents() */
unsigned short d_reclen; /* Rozmiar tego dirent */
unsigned char d_type; /* Typ pliku */
char d_name[]; /* Nazwa pliku (zakończona null) */
};
WARTOŚĆ ZWRACANA
Po pomyślnym zakończeniu zwracana jest ilość odczytanych bajtów. Na końcu katalogu zwracane jest 0. Przy
błędzie zwracane jest -1 i ustawiane errno wskazując błąd.
BŁĘDY
EBADF Nieprawidłowy deskryptor fd.
EFAULT Argument wskazuje poza przestrzeń adresową wywołującego procesu.
EINVAL Bufor na wynik jest za mały.
ENOENT Nie ma takiego katalogu.
ENOTDIR
Deskryptor pliku nie odnosi się do katalogu.
STANDARDY
Brak.
HISTORIA
SVr4.
getdents64()
glibc 2.30.
UWAGI
glibc nie udostępnia opakowania dla getdents(); należy je wywołać za pomocą syscall(2). W takim przypadku
konieczne będzie samodzielne zdefiniowanie struktury linux_dirent lub linux_dirent64.
Zamiast opisywanych wywołań systemowych, prawdopodobnie lepszym pomysłem będzie użycie readdir(3).
Te wywołania zastępują readdir(2).
PRZYKŁADY
Program poniżej demonstruje użycie getdents(). Poniższe wyjście pokazuje przykład, w którym można
zaobserwować działanie tego programu w katalogu ext2:
$ ./a.out /testfs/
--------------- nread=120 ---------------
i-węzeł# typ pliku d_reclen d_off d_name
2 katalog 16 12 .
2 katalog 16 24 ..
11 katalog 24 44 lost+found
12 zwykły 16 56 a
228929 katalog 16 68 sub
16353 katalog 16 80 sub2
130817 katalog 16 4096 sub3
Kod źródłowy programu
#define _GNU_SOURCE
#include <dirent.h> /* Definiuje stałe DT_* */
#include <err.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/types.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("i-węzeł# typ pliku 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) ? "zwykły" :
(d_type == DT_DIR) ? "katalog" :
(d_type == DT_FIFO) ? "FIFO" :
(d_type == DT_SOCK) ? "gniazdo" :
(d_type == DT_LNK) ? "dow. symbol." :
(d_type == DT_BLK) ? "urz. blok." :
(d_type == DT_CHR) ? "urz. znak." : "???");
printf("%4d %10jd %s\n", d->d_reclen,
(intmax_t) d->d_off, d->d_name);
bpos += d->d_reclen;
}
}
exit(EXIT_SUCCESS);
}
ZOBACZ TAKŻE
readdir(2), readdir(3), inode(7)
TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz
<ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać
zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ
ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-
list@lists.sourceforge.net.
Linux man-pages 6.9.1 15 czerwca 2024 r. getdents(2)