getdents(2) System Calls Manual getdents(2) NAZWA getdents, getdents64 - pobiera wpisy z katalogu BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include /* Definicja stalych SYS_* */ #include long syscall(SYS_getdents, unsigned int fd, struct linux_dirent *dirp, unsigned int count); #define _GNU_SOURCE /* Zob. feature_test_macros(7) */ #include ssize_t getdents64(int fd, void dirp[.count], size_t count); Uwaga: glibc nie udostepnia opakowania dla getdents(), co wymusza uzycie syscall(2). Note: W glibc brak definicji struct linux_dirent; zob. UWAGI. OPIS Nie sa to interfejsy, ktore cie interesuja. Opis implementacji interfejsu zgodnego z POSIX w bibliotece C znajduje sie w readdir(3). Niniejsza strona opisuje nagi interfejs wywolania systemowego. getdents() Wywolanie systemowe getdents() odczytuje kolejne struktury linux_dirent z katalogu wskazywanego przez przez deskryptor otwartego pliku fd do bufora wskazywanego przez dirp. Argument count okresla rozmiar tego bufora. Struktura linux_dirent jest zadeklarowana nastepujaco: struct linux_dirent { unsigned long d_ino; /* Numer i-wezla */ unsigned long d_off; /* Przesun. do nast. linux_dirent */ unsigned short d_reclen; /* Dlugosc tego linux_dirent */ char d_name[]; /* Nazwa pliku (zakoncz. znakiem null) */ /* dlugosc to faktycznie (d_reclen - 2 - offsetof(struct linux_dirent, d_name)) */ /* char pad; // Zerowy bajt wyrownania char d_type; // Typ pliku (tylko od Linuksa // 2.6.4); przesunieciem jest (d_reclen - 1) */ } d_ino jest numerem i-wezla. d_off jest odlegloscia od poczatku katalogu do poczatku nastepnej struktury linux_dirent. d_reclen jest wielkoscia tej calej struktury linux_dirent. d_name jest nazwa pliku zakonczona znakiem NUL. d_type jest bajtem na koncu struktury wskazujacym typ pliku. Zawiera jedna z nastepujacych wartosci (zdefiniowanym w ): DT_BLK Jest to urzadzenie blokowe DT_CHR Jest to urzadzenie znakowe. DT_DIR Jest to katalog. DT_FIFO Jest to potok nazwany (FIFO). DT_LNK Jest to dowiazanie symboliczne. DT_REG Jest to zwykly 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, ktore wczesniej zajmowal zerowy bajt wypelnienia w strukturze linux_dirent. Z tego wzgledu jadra do Linuksa 2.6.3, probujace uzyskac dostep do tego pola zawsze zwracaja wartosc 0 (DT_UNKNOWN). Obecnie jedynie niektore systemy plikow (m.in Btrfs, ext2, ext3 i ext4) obsluguja w pelni zwracanie typu pliku w d_type. Wszystkie programy musza poprawnie obslugiwac zwrocenie wartosci DT_UNKNOWN. getdents64() Pierwotne, linuksowe wywolanie getdents() nie obslugiwalo duzych systemow plikow i duzych przesuniec pliku. Z tego powodu, Linux 2.4 dodal getdents64(), z szerszymi typami pol d_ino i d_off. Dodatkowo, getdents64() obsluguje wprost pole d_type. Wywolanie systemowe getdents64() zachowuje sie jak getdents(), tyle ze jego drugi argument jest wskaznikiem do bufora zawierajacego strukture nastepujacego typu: struct linux_dirent64 { ino64_t d_ino; /* 64-bitowy numer i-wezla */ off64_t d_off; /* 64-bitowy przesun. do nastepnej strukt. */ unsigned short d_reclen; /* Rozmiar tego dirent */ unsigned char d_type; /* Typ pliku */ char d_name[]; /* Nazwa pliku (zakonczona null) */ }; WARTOSC ZWRACANA Po pomyslnym zakonczeniu zwracana jest ilosc odczytanych bajtow. Na koncu katalogu zwracane jest 0. Przy bledzie zwracane jest -1 i ustawiane errno wskazujac blad. BLEDY EBADF Nieprawidlowy deskryptor fd. EFAULT Argument wskazuje poza przestrzen adresowa wywolujacego procesu. EINVAL Bufor na wynik jest za maly. ENOENT Nie ma takiego katalogu. ENOTDIR Deskryptor pliku nie odnosi sie do katalogu. STANDARDY Brak. HISTORIA SVr4. getdents64() glibc 2.30. UWAGI glibc nie udostepnia opakowania dla getdents(); nalezy je wywolac za pomoca syscall(2). W takim przypadku konieczne bedzie samodzielne zdefiniowanie struktury linux_dirent lub linux_dirent64. Zamiast opisywanych wywolan systemowych, prawdopodobnie lepszym pomyslem bedzie uzycie readdir(3). Te wywolania zastepuja readdir(2). PRZYKLADY Program ponizej demonstruje uzycie getdents(). Ponizsze wyjscie pokazuje przyklad, w ktorym mozna zaobserwowac dzialanie tego programu w katalogu ext2: $ ./a.out /testfs/ --------------- nread=120 --------------- i-wezel# typ pliku d_reclen d_off d_name 2 katalog 16 12 . 2 katalog 16 24 .. 11 katalog 24 44 lost+found 12 zwykly 16 56 a 228929 katalog 16 68 sub 16353 katalog 16 80 sub2 130817 katalog 16 4096 sub3 Kod zrodlowy programu #define _GNU_SOURCE #include /* Definiuje stale DT_* */ #include #include #include #include #include #include #include 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-wezel# 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) ? "zwykly" : (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 TAKZE readdir(2), readdir(3), inode(7) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Przemek Borys , Andrzej Krzysztofowicz i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.06 31 pazdziernika 2023 r. getdents(2)