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

ЖАНРЫ

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

• 

chdir
и
fchdir
дают процессу возможность изменить его текущий каталог,
getcwd
получает абсолютное имя пути текущего каталога. Эти три функции просты в использовании.

• Функция

nftw
централизует задачу «обхода дерева файлов», т.е. посещения каждого объекта файловой системы (файла, устройства, символической ссылки, каталога) во всей иерархии каталогов. Ее поведением управляют различные флаги. Программист должен предоставить функцию обратного вызова, которая получает имя каждого файла,
struct stat
для файла, тип файла и сведения об имени файла и уровне в иерархии. Эта функция может делать
для каждого файла все что нужно. Версия функции
du
из Coreutils 5.0 GNU использует для выполнения этой работы расширенную версию
nftw
.

• Наконец, системный вызов

chroot
изменяет текущий корневой каталог процесса. Это специализированная, но важная возможность, которая особенно полезна для определенных программ в стиле демонов.

Упражнения

1. Изучите справочную страницу mount(2) под GNU/Linux и на всех различных системах Unix, к которым у вас есть доступ. Как отличаются системные вызовы?

2. Усовершенствуйте программу

ch08-statvfs.c
, чтобы она принимала опцию, предоставляющую открытый целый дескриптор файла; для получения сведений о файловой системе она должна использовать
fstatvfs
.

3. Усовершенствуйте

ch08-statvfs.c
, чтобы она не игнорировала смонтированные файловые системы NFS. Такие файловые системы имеют устройство в форме
server.example.com:/big/disk
.

4. Измените

ch08-statfs.c
(ту, которая использует специфичный для Linux вызов
statfs
), чтобы ее вывод был похож на вывод
df
.

5. Добавьте опцию

– i
к программе, которую вы написали для предыдущего упражнения, чтобы ее вывод был такой же, как у '
df -i
'.

6. Используя

opendir
,
readdir
,
stat
или
fstat
,
dirfd
и
fchdir
, напишите собственную версию
getcwd
. Как вы вычислите общий размер, который должен иметь буфер? Как вы будете перемещаться по иерархии каталогов?

7. Усовершенствуйте свою версию

getcwd
, чтобы она выделяла буфер для вызывающего, если первый аргумент равен NULL.

8. Можете ли вы использовать

nftw
для написания
getcwd
? Если нет, почему?

9. Используя

nftw
, напишите свою собственную версию
chown
, которая принимает опцию
– R
для рекурсивной обработки целых деревьев каталогов. Убедитесь, что без
– R
, '
chown пользователь каталог
' не является рекурсивной. Как вы это проверите?

10. Набор процедур BSD

fts
(«file tree stream» — «поток дерева файлов») предоставляет другой способ для обработки иерархии каталогов. У него несколько более тяжелый API как в смысле числа функций, так и структур, которые доступны для вызывающих функций уровня пользователя. Эти функции доступны как стандартная часть GLIBC.

Прочтите справочную страницу fts(3). (Для удобства ее можно распечатать.) Перепишите свою частную версию chown для использования

fts
.

11. Посмотрите справочную страницу find(1). Если бы вы пытались написать

find
с самого начала, какой набор деревьев файлов
вы бы предпочли,
nftw
или
fts
? Почему?

Часть 2

Процессы, IPC и интернационализация

Глава 9

Управление процессами и каналы

Как мы говорили в главе 1 «Введение», если бы нужно было резюмировать Unix (а следовательно, и Linux) в трёх словах, это были бы «файлы и процессы». Теперь, когда мы увидели, как работать с файлами и каталогами, время взглянуть на оставшуюся часть утверждения: процессы. В частности, мы исследуем, как создаются и управляются процессы, как они взаимодействуют с открытыми файлами и как они могут взаимодействовать друге другом. Последующие главы исследуют сигналы — грубый способ дать возможность одному процессу (или ядру) сообщить другому о том, что произошло некоторое событие — и проверку прав доступа.

В данной главе картина начинает усложняться. В частности, для полноты мы должны упомянуть о вещах, которые не будут рассматриваться до конца главы или до конца книги В таких случаях мы предусмотрели ссылки вперед, но вы должны быть способны без подготовки уловить суть каждого раздела.

9.1. Создание и управление процессами

В отличие от многих предшествующих и последующих операционных систем, создание процессов в Unix задумывалось (и было сделано) дешевым. Более того, Unix разделяет идеи «создания нового процесса» и «запуска данной программы в процессе». Это было элегантное проектное решение, которое упрощает многие операции.

9.1.1. Создание процесса:

fork

Первым шагом в запуске новой программы является вызов

fork
:

#include <sys/types.h> /* POSIX */

#include <unistd.h>

pid_t fork(void);

Использование

fork
просто. Перед вызовом один процесс, который мы называем родительским, является запущенным. Когда
fork
возвращается, имеется уже два процесса: родительский и порожденный (child).

Вот ключ: оба процесса выполняют одну и ту же программу. Два процесса могут различить себя, основываясь на возвращённом

fork
значении:

Отрицательное

Если была ошибка,

fork
возвращает -1, а новый процесс не создается. Работу продолжает первоначальный процесс.

Нулевое

В порожденном процессе

fork
возвращает 0.

Положительное

В родительском процессе

fork
возвращает положительный идентификационный номер (PID) порожденного процесса.

Код шаблона для создания порожденного процесса выглядит следующим образом:

pid_t child;

if ((child = fork) < 0)

 /* обработать ошибку */

else if (child == 0)

 /* это новый процесс */

else

 /* это первоначальный родительский процесс */

pid_t
является знаковым целым типом для хранения значений PID. Скорее всего, это просто
int
, но специальный тип делает код более понятным, поэтому он должен использоваться вместо
int
.

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