Чтение онлайн

ЖАНРЫ

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

3. Вызовите функцию

closedir
, передав ей имеющийся дескриптор, чтобы завершить сеанс работы с каталогом.

Для использования перечисленных функций необходимо включить в программу файлы

<sys/types.h>
и
<dirent.h>
. Ответственность за сортировку содержимого каталога возлагается на программу.

В листинге Б.8 показана программа отображающая список содержимого каталога. Имя каталога задается в командной строке. Если этого не сделать, будет проанализирован текущий каталог. Для каждого элемента каталога отображается его тип и путевое имя. Функция

get_file_type
определяет тип объекта
файловой системы с помощью функции
lstat
.

Листинг Б.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] = '\0';

++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: %s\n", 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 перечислены сигналы, которые чаще всего приходится обрабатывать в Linux-программах. Некоторые сигналы имеют разные интерпретации в зависимости от того, где они были получены.

Указанные имена сигналов определены в виде макроконстант препроцессора. Чтобы иметь возможность сослаться на них в программе необходимо подключить файл

<signal.h>
. Реальное определение сигналов дано в файле
/usr/sys/signum.h
, который подключается к файлу
<signal.h>
.

Поделиться с друзьями: