versionsort - ищет записи в каталоге
versionsort(3)
ищет записи в каталоге
Other Alias
scandir, scandirat, alphasort
ОБЗОР
#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);
}
}