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

Упражнения

Упражнения

1. Напишите программу, которая выводит как можно больше сведений о текущем процессе: PID, PPID, открытые файлы, текущий каталог, значение относительного приоритета и т.д. Как вы можете сказать, какие файлы открыты? Если несколько дескрипторов файлов ссылаются на один и тот же файл, укажите это. (Опять-таки, как вы можете это узнать?)

2. Как вы думаете, atexit() хранит указатели на функции обратного вызова? Реализуйте atexit(), держа в уме принцип GNU «никаких произвольных ограничений». Набросайте схему (псевдокод) для exit(). Каких сведений (внутренностей библиотеки <stdio.h>) вам не хватает, чтобы написать exit()?

3. Программа xargs предназначена для многократных запусков команды и аргументов, когда аргументов слишком много для непосредственного набора в командной строке. Программа работает, считывая строки из стандартного ввода, рассматривая каждую строку в качестве отдельного аргумента для указанной команды, и упаковывая аргументы до тех пор, пока они остаются в пределах максимально допустимого для системы. Например:

$ grep ARG_MAX /usr/include/*.h /usr/include/*/*.h /* Командная строка */
bash: /bin/grep: Argument list too long /* Сообщение оболочки об ошибке */
$ find /usr/include -name '*.h' | xargs grep ARG_MAX /* find b xargs работают */
/usr/include/sys/param.h:#define NCARGS ARG_MAX
...

Константа ARG_MAX в <limits.h> представляет сочетание общей памяти, используемой средой, и аргументов командной строки. Стандарт POSIX не говорит, включает ли это массивы указателей или просто сами строки.

Напишите простую версию xargs, которая работает указанным способом. Не забудьте об окружении при вычислении размера необходимого пространства. Убедитесь, что тщательно управляете памятью.

4. Компоновка значения status, заполняемого функциями wait() и waitpid(), стандартом POSIX не определяется. Хотя и историческое, это 16-разрядное значение, которое выглядит, как показано на рис. 9.8.


Рис. 9.8. Компоновка значения status функции wait()

 • Ненулевое значение в битах 0–7 указывает на завершение по сигналу.

 • Все единичные биты в поле сигнала указывает, что порожденный процесс остановлен. В этом случае биты 9-15 содержат номер сигнала.

 • Единичное значение бита 8 указывает завершение со снимком процесса.

 • Если биты 0–7 равны нулю, процесс завершился нормально. В этом случае биты 9–15 являются статусом завершения.

Напишите с данными сведениями макросы POSIX WIFEXITED() и др.

5. Помня, что dup2() сначала закрывает запрошенный дескриптор файла, реализуйте dup2(), используя close() и fcntl(). Как вы обработаете случай, когда fcntl() возвращает значение меньше запрошенного?

6. Есть ли на вашей системе каталог /dev/fd? Если есть, как он реализован?

7. Напишите новую версию ch09-pipeline.c, которая порождает лишь один процесс. После порождения родитель должен поменять дескрипторы своих файлов и сам выполнить exec для одной из новых программ.

8. (Трудное) Как вы можете узнать, вызывал ли ваш процесс когда-нибудь chroot()? Напишите программу, которая проверяет это и выводит сообщение с ответом да или нет. Можно ли обмануть вашу программу? Если да, как?

9. Есть ли на вашей системе каталог /proc? Если да, доступ к какой информации о процессе он обеспечивает?

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


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