Книга: Программирование для 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

Первый символ каждой строки определяет тип элемента каталога.

Оглавление книги


Генерация: 1.265. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз