Provided by: manpages-pl-dev_4.23.1-1_all bug

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

       Autorami  polskiego  tłumaczenia  niniejszej  strony   podręcznika   są:   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
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  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⟩.