ИМЯ
getdents, getdents64 - возвращает записи каталогаLIBRARY
Standard C library ( libc, -lc)СИНТАКСИС
#include <sys/syscall.h> /* определения констант SYS_* */ #include <unistd.h>
long syscall(SYS_getdents, unsigned int fd, struct linux_dirent *dirp, unsigned int count);
#define _GNU_SOURCE /* Смотрите feature_test_macros(7) */ #include <dirent.h>
ssize_t getdents64(int fd, void dirp[.count], size_t count);Note: glibc provides no wrapper for getdents(), necessitating the use of syscall(2). Note: There is no definition of struct linux_dirent in glibc; see NOTES.
ОПИСАНИЕ
Это не те функции, которые должны представлять для вас интерес. Смотрите описание функции readdir(3), которая является интерфейсом библиотеки языка C, соответствующим стандарту POSIX. В этой странице описаны минимальные интерфейсы системных вызовов ядра.getdents()
Системный вызов getdents() читает несколько структур linux_dirent из каталога, на который указывает открытый файловый дескриптор fd, в буфер, указанный в dirp. В аргументе count задаётся размер этого буфера. Структура linux_dirent определена следующим образом:struct linux_dirent { unsigned long d_ino; /* номер иноды */ unsigned long d_off; /* смещение до следующей linux_dirent */ unsigned short d_reclen; /* длина этой linux_dirent */ char d_name[]; /* имя файла (в конце null) */ /* реальная длина (d_reclen - 2 - offsetof(struct linux_dirent, d_name)) */ /* char pad; // нулевой байт заполнения char d_type; // тип файла (только начиная с Linux // 2.6.4); смещение (d_reclen - 1) */ }
В d_ino указан номер inode. В d_off задаётся расстояние от начала каталога до начала следующей linux_dirent. В d_reclen указывается размер данного linux_dirent целиком. В d_name задаётся имя файла, завершающееся null. d_type — байт в конце структуры, которым определяется тип файла. В нём содержится одно из следующих значений (определённых в <dirent.h>):
- DT_BLK
- блочное устройство
- DT_CHR
- символьное устройство
- DT_DIR
- каталог
- DT_FIFO
- именованный канал (FIFO)
- DT_LNK
- символическая ссылка
- DT_REG
- обычный файл
- DT_SOCK
- доменный сокет UNIX
- DT_UNKNOWN
- Неизвестный тип.
getdents64()
Первоначальный системный вызов Linux getdents() не работал с файловыми системами большого размера и большими смещениями файлов. В связи с этим, в Linux 2.4 была добавлен getdents64(), с более широкими типами полей d_ino и d_off. Также getdents64() поддерживает явно указанное поле d_type. Системный вызов getdents64() подобен getdents(), за исключением того, что второй аргумент является указателем на буфер, содержащий структуры следующего типа:struct linux_dirent64 { ino64_t d_ino; /* 64-битный номер иноды */ off64_t d_off; /* 64-битное смещение следующей структуры */ unsigned short d_reclen; /* размер этой dirent */ unsigned char d_type; /* тип файла */ char d_name[]; /* имя файла (в конце null) */ };
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
On success, the number of bytes read is returned. On end of directory, 0 is returned. On error, -1 is returned, and errno is set to indicate the error.ОШИБКИ
- EBADF
- Неверный файловый дескриптор fd.
- EFAULT
- Аргумент указывает за пределы адресного пространства вызывающего процесса.
- EINVAL
- Буфер результата слишком мал.
- ENOENT
- Заданный каталог не существует.
- ENOTDIR
- Файловый дескриптор указывает не на каталог.
СТАНДАРТЫ
SVr4.ЗАМЕЧАНИЯ
Library support for getdents64() was added in glibc 2.30; glibc does not provide a wrapper for getdents(); call getdents() (or getdents64() on earlier glibc versions) using syscall(2). In that case you will need to define the linux_dirent or linux_dirent64 structure yourself. Probably, you want to use readdir(3) instead of these system calls. Данные системные вызовы заместил readdir(2).ПРИМЕРЫ
В программе, показанной далее, демонстрируется использование getdents(). В следующем выводе показан пример запуска этой программы с каталогом с ext2:$ ./a.out /testfs/ --------------- nread=120 --------------- inode# 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
Исходный код программы
#define _GNU_SOURCE #include <dirent.h> /* Определяет константы DT_* */ #include <err.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <sys/syscall.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("inode# file type 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) ? "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 %10jd %s\n", d->d_reclen, (intmax_t) d->d_off, d->d_name); bpos += d->d_reclen; } } exit(EXIT_SUCCESS); }
СМ. ТАКЖЕ
readdir(2), readdir(3), inode(7)ПЕРЕВОД
Русский перевод этой страницы руководства был сделан Azamat Hackimov <[email protected]>, Dmitry Bolkhovskikh <[email protected]>, Vladislav <[email protected]>, Yuri Kozlov <[email protected]> и Иван Павлов <[email protected]> Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на [email protected]5 февраля 2023 г. | Linux man-pages 6.03 |