Other Alias
scandir, scandirat, versionsortОБЗОР
#include <dirent.h>
int scandir(const char *dirp, struct dirent ***namelist,
- int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **));
int alphasort(const struct dirent **a, const struct dirent **b);
int versionsort(const struct dirent **a, const struct dirent **b); #include <fcntl.h> /* определения констант AT_* */ #include <dirent.h>
int scandirat(int dirfd, const char *dirp, struct dirent ***namelist,
- int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **));
Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):
scandir(), alphasort():
-
_BSD_SOURCE || _SVID_SOURCE
|| /* Начиная с glibc 2.10: */- (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
versionsort(): _GNU_SOURCE
scandirat(): _GNU_SOURCE
ОПИСАНИЕ
Функция scandir() обходит каталог dirp, вызывая filter() для каждой записи каталога. Записи, для которых filter() возвращает не ноль, сохраняются в строках, выделяемых с помощью malloc(3), сортируются qsort(3) с помощью функции сравнения compar() и собираются в массиве namelist, который выделяется с помощью malloc(3). Если filter равно NULL, то выбираются все записи.В качестве функции сравнения compar() можно использовать alphasort() и versionsort(). Первая сортирует записи (строки (*a)->d_name и (*b)->d_name) каталога с помощью strcoll(3), а последняя с помощью strverscmp(3).
scandirat()
Системный вызов scandirat() работает также как системный вызов scandir(), за исключением случаев, описанных здесь.Если в dirp задан относительный путь, то он считается относительно каталога, на который ссылается файловый дескриптор dirfd (а не относительно текущего рабочего каталога вызывающего процесса, как это делается в scandir()).
Если в dirp задан относительный путь и значение dirfd равно AT_FDCWD, то dirp рассматривается относительно текущего рабочего каталога вызывающего процесса (как scandir()).
Если в dirp задан абсолютный путь, то dirfd игнорируется.
Смотрите в openat(2) объяснение необходимости scandirat().
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении scandir() возвращается количество выбранных записей каталога. При ошибке возвращается -1, а в errno содержится код ошибки.Функции alphasort() и versionsort() возвращают целое, меньшее, равное или большее нуля, если первый аргумент считается меньшим, равным или большим чем второй, соответственно.
ОШИБКИ
- ENOENT
- Путь в dirp не существует.
- ENOMEM
- Недостаточно памяти для завершения операции.
- ENOTDIR
- Путь в dirp не является каталогом.
В scandirat() дополнительно могут возникнуть следующие ошибки:
- EBADF
- Значение dirfd не является правильным файловым дескриптором.
- ENOTDIR
- Значение dirp содержит относительный путь и dirfd содержит файловый дескриптор, указывающий на файл, а не на каталог.
ВЕРСИИ
Функция versionsort() впервые появилась в glibc 2.1.Функция scandirat() впервые появилась в glibc 2.15.
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).Интерфейс | Атрибут | Значение |
scandir(), scandirat() | безвредность в нитях | безвредно (MT-Safe) |
alphasort(), versionsort() | безвредность в нитях | безвредно (MT-Safe locale) |
СООТВЕТСТВИЕ СТАНДАРТАМ
alphasort(), scandir(): 4.3BSD, POSIX.1-2008.Функции versionsort() и scandirat() являются расширениями GNU.
ЗАМЕЧАНИЯ
Начиная с glibc 2.1, alphasort() вызывает strcoll(3); раньше в ней использовалась strcmp(3).До glibc 2.10, два аргумента alphasort() и versionsort() имели тип const void *. После стандартизации alphasort() в POSIX.1-2008, тип аргумента argument стал типобезопасным const struct dirent **, и в glibc 2.10 функция alphasort() (и нестандартная versionsort()) была приведена в соответствие со стандартом.
ПРИМЕР
#define _SVID_SOURCE /* печатает файлы текущего каталога в обратном порядке */ #include <dirent.h> int main(void) { struct dirent **namelist; int n; n = scandir(".", &namelist, NULL, alphasort); if (n < 0) perror("scandir"); else { while (n--) { printf("%s\n", namelist[n]->d_name); free(namelist[n]); } free(namelist); } }