Книга: Программирование для Linux. Профессиональный подход
Листинг Б.8. (listdir.c) Вывод содержимого каталога
Листинг Б.8. (listdir.c) Вывод содержимого каталога
#include <assert.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/* Эта функция возвращает строку с описанием типа объекта
файловой системы, заданного в аргументе PATH. */
const char* get_file_type(const char* path) {
struct stat st;
lstat(path, &st);
if (S_ISLNK(st.st_mode))
return "symbolic link";
else if (S_ISDIR(st.st_mode))
return "directory";
else if (S_ISCHR(st.st_mode))
return "character device";
else if (S_ISBLK(st.st_mode))
return "block device";
else if (S_ISFIFO(st.st_mode))
return "fifo";
else if (S_ISSOCK(st.st_mode))
return "socket";
else if (S_ISREG(st.st_mode))
return "regular file";
else
/* Нераспознанный тип. */
assert(0);
}
int main(int argc, char* argv[]) {
char* dir_path;
DIR* dir;
struct dirent* entry;
char entry_path[PATH_MAX + 1];
size_t path_len;
if (argc >= 2)
/* Если каталог указан в командной строке, анализируем его. */
dir_path = argv[1];
else
/* В противном случае анализируем текущий каталог. */
dir_path = ".";
/* Копируем имя каталога в переменную entry_path. */
strncpy(entry_path, dir_path, sizeof(entry_path));
path_len = strlen(dir_path);
/* Если имя каталога не заканчивается косой чертой,
добавляем ее. */
if (entry_path[path_len - 1] != '/') {
entry_path[path_len] = '/';
entry_path[path_len + 1] = '';
++path_len;
}
/* Начинаем обрабатывать список содержимого каталога. */
dir = opendir(dir_path);
/* просматриваем все элементы каталога. */
while ((entry = readdir(dir)) != NULL) {
const char* type;
/* Формируем полное путевое имя элемента каталога. */
strncpy(entry_path + path_len, entry->d_name,
sizeof(entry_path) — path_len);
/* Определяем тип элемента. */
type = get_file_type(entry_path);
/* Отображаем собранную информацию. */
printf("%-18s: %sn", type, entry_path);
}
/* Конец работы. */
closedir(dir);
return 0;
}
Приведем несколько строк листинга полученного в каталоге /dev
(в разных системах могут быть выданы разные результаты)
% ./listdir /dev
directory : /dev/.
directory : /dev/..
socket : /dev/log
character device : /dev/null
regular file : /dev/MAKEDEV
fifo : /dev/initctl
character device : /dev/agpgart
...
Для проверки этих данных можно воспользоваться командой ls
. Флаг -U
отменяет сортировку списка, а флаг -a
заставляет включить в список записи текущего (.
) и родительского (..
) каталогов.
% ls -lua /dev total 124
drwxr-xr-x 7 root root 36864 Feb 1 15:14 .
drwxr-xr-x 22 root root 4096 Oct 11 16:39 ..
srw-rw-rw- 1 root root 0 Dec 18 01:31 log
crw-rw-rw- 1 root root 1, 3 May 5 1998 null
-rwxr-xr-x 1 root root 26689 Mar 2 2000 MAKEDEV
prw------- 1 root root 0 Dec 11 18:37 initctl
crw-rw-r-- 1 root root 10, 175 Feb 3 2000 agpgart
Первый символ каждой строки определяет тип элемента каталога.
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Включение и отключение синхронного вывода
- Использование типов содержимого и столбцов
- Листинг 15.11. Код для загрузки файла с Web-сервера
- 2. Правила вывода Армстронга
- 3. Производные правила вывода
- 1.6 Драйверы и буферы ввода-вывода
- 1.8 Ввод-вывод типичного приложения хранения данных
- Управление объединением содержимого узлов
- Создание столбцов и работа с типами содержимого
- Глава 6 BIOS – базовая система ввода-вывода
- Пример использования шаблона «Выводы – рекомендации»