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  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.8                              2 maja 2024 r.                                      getdents(2)