Операционная система UNIX - страница 81
>
>#endif
>}
Запуск программы под управлением операционной системы Solaris 2.5 даст следующие результаты:
>$ а.out
>RLIMIT_CORE infinite infinite
>RLIMIT_CPU infinite infinite
>RLIMIT_DATA 2147479552 2147479552
>RLIMIT_FSIZE infinite infinite
>RLIMIT_NOFILE 64 1024
>RLIMIT_STACK 8388608 2147479552
>RLIMIT_VMEM infinite infinite
Примеры программ
В качестве заключительной иллюстрации к обсуждавшимся выше вопросам приводятся фрагменты двух приложений, которые в достаточной степени демонстрируют практическое применение программного интерфейса UNIX. Заметим, что приведенные примеры не являются законченными программами — во многих местах участки кода намеренно опущены, а функциональность сведена к минимуму. Задачей являлось показать принцип взаимодействия программ с операционной системой и идеологию программирования в UNIX. Рассмотрим два диаметрально противоположных приложения — неинтерактивную программу-демон и интерактивный командный интерпретатор.
Демон
Демоны играют важную роль в работе операционной системы. Достаточно будет сказать, что возможность терминального входа пользователей в систему, доступ по сети, использование системы печати и электронной почты, — все это обеспечивается соответствующими демонами — неинтерактивными программами, составляющими собственные сеансы (и группы) и не принадлежащими ни одному из пользовательских сеансов (групп).
Некоторые демоны работают постоянно, наиболее яркий пример такого демона — процесс init(1M), являющийся прародителем всех прикладных процессов в системе. Другими примерами являются cron(1M), позволяющий запускать программы в определенные моменты времени, inetd(1M) обеспечивающий доступ к сервисам системы из сети, и sendmail(1M), обеспечивающий получение и отправку электронной почты.
При описании взаимодействия процессов с терминалом и пользователем в разделе "Группы и сеансы", отмечалось особое место демонов, которые не имеют управляющего терминала. Теперь в отношении демонов можно сформулировать ряд правил, определяющих их нормальное функционирование, которые необходимо учитывать при разработке таких программ:
1. Демон не должен реагировать на сигналы управления заданиями, посылаемые ему при попытке операций ввода/вывода с управляющим терминалом. Начиная с некоторого времени, демон снимает ассоциацию с управляющим терминалом, но на начальном этапе запуска ему может потребоваться вывести то или иное сообщение на экран.
2. Необходимо закрыть все открытые файлы (файловые дескрипторы), особенно стандартные потоки ввода/вывода. Многие из этих файлов представляют собой терминальные устройства, которые должны быть закрыты, например, при выходе пользователя из системы. Предполагается, что демон остается работать и после того, как пользователь "покинул" UNIX.
3. Необходимо снять его ассоциацию с группой процессов и управляющим терминалом. Это позволит демону избавиться от сигналов, генерируемых терминалом (>SIGINT
или >SIGHUP
), например, при нажатии определенных клавиш или выходе пользователя из системы.
4. Сообщения о работе демона следует направлять в специальный журнал с помощью функции syslog(3), — это наиболее корректный способ передачи сообщений от демона.
5. Необходимо изменить текущий каталог на корневой. Если этого не сделать, а текущий каталог, допустим, находится на примонтированной файловой системе, последнюю нельзя будет размонтировать. Самым надежным выбором является корневой каталог, всегда принадлежащий корневой файловой системе.
Приведем скелет программы-демона:
>#include
>#include
>#include
>#include
>#include
>#include
>main(int argc, char **argv) {
> int fd;
> struct rlimit flim;
> /* Если родительский процесс — init, можно не беспокоиться
> за терминальные сигналы. Если нет — необходимо игнорировать
> сигналы, связанные с вводом/выводом на терминал
> фонового процесса: SIGTTOU, SIGTTIN, SIGTSTP */
> if (getppid() != 1) {
> signal(SIGTTOU, SIG_IGN);
> signal(SIGTTIN, SIG_IGN);
> signal(SIGTSTP, SIG_IGN);
> /* Теперь необходимо организовать собственную группу и сеанс,