Андрей Робачевский - Операционная система UNIX
- Название:Операционная система UNIX
- Автор:
- Жанр:
- Издательство:BHV - Санкт-Петербург
- Год:1997
- Город:Санкт-Петербург
- ISBN:5-7791-0057-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Андрей Робачевский - Операционная система UNIX краткое содержание
Книга посвящена семейству операционных систем UNIX и содержит информацию о принципах организации, идеологии и архитектуре, объединяющих различные версии этой операционной системы.
В книге рассматриваются: архитектура ядра UNIX (подсистемы ввода/вывода, управления памятью и процессами, а также файловая подсистема), программный интерфейс UNIX (системные вызовы и основные библиотечные функции), пользовательская среда (командный интерпретатор shell, основные команды и утилиты) и сетевая поддержка в UNIX (протоколов семейства TCP/IP, архитектура сетевой подсистемы, программные интерфейсы сокетов и TLI).
Для широкого круга пользователей
Операционная система UNIX - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
}
/* Теперь необходимо закрыть открытые файлы. Закроем
все возможные файловые дескрипторы. Максимальное число
открытых файлов получим с помощью функции getrlimit */
getrlimit(RLIMIT_NOFILE, &flim);
for (fd = 0; fd < flim.rlim_max; fd++)
close(fd);
/* Сменим текущий каталог на корневой */
chdir("/");
/* Заявим о себе в системном журнале. Для этого сначала
установим опции ведения журнала: каждая запись будет
предваряться идентификатором PID демона, при невозможности
записи в журнал сообщения будут выводиться на консоль,
источник сообщений определим как "системный демон"
(см. комментарии к функциям ведения журнала ниже). */
openlog("Скелет демона" , LOG_PID | LOG_CONS, LOG_DAEMON);
/* Отметимся */
syslog(LOG_INFO, "Демон начал плодотворную работу...");
closelog();
/* Далее следует текст программы, реализующий полезные функции
демона. Эта часть предоставляется читателю для собственной
разработки. */
...
}
В программе использовалось еще не обсуждавшаяся возможность системного журнала сообщений выполняющихся программ. Функцией генерации сообщений является syslog(3) , отправляющая сообщение демону системного журнала syslogd(1M) , который в свою очередь либо дописывает сообщения в системный журнал, либо выводит на их консоль, либо перенаправляет в соответствии со списком пользователей данной или удаленной системы. Конкретный пункт назначения определяется конфигурационным файлом ( /etc/syslog.conf). Функция имеет определение:
#include
void syslog(int priority, char *logstring, /* параметры*/...);
Каждому сообщению logstring
назначается приоритет, указанный параметром priority
. Возможные значения этого параметра включают:
LOG_EMERG |
Идентифицирует состояние "паники" в системе. Обычно рассылается всем пользователям. |
LOG_ALERT |
Идентифицирует ненормальное состояние, которое должно быть исправлено немедленно, например, нарушение целостности системной базы данных. |
LOG_CRIT |
Идентифицирует критическое событие, например, ошибку дискового устройства. |
LOG_ERR |
Идентифицирует различные ошибки. |
LOG_WARNING |
Идентифицирует предупреждения. |
LOG_NOTICE |
Идентифицирует события, которые не являются ошибками, но требуют внимания. |
LOG_INFO |
Идентифицирует информационные сообщения, как, например, использованное в приведенной программе. |
LOG_DEBUG |
Идентифицирует сообщение, обычно используемое только при отладке программы. |
Последний тип сообщений подсказывает еще одну возможность использования системного журнала — для отладки программ, особенно неинтерактивных.
Строка logstring
может включать элементы форматирования, такие же, как и в функции printf(3) , с одним дополнительным выражением %m
, которое заменяется сообщением, соответствующим ошибке errno
. При этом может осуществляться вывод значений дополнительных параметров.
Функция openlog(3) позволяет определить ряд опций ведения журнала. Она имеет следующее определение:
void openlog(char *ident, int logopt, int facility);
Строка ident
будет предшествовать каждому сообщению программы. Аргумент logopt
задает дополнительные опции, в том числе:
LOG_PID |
Позволяет указывать идентификатор процесса в каждом сообщении. Эта опция полезна при журналировании нескольких демонов с одним и тем же значением ident, например, когда демоны порождаются вызовом fork(2) . |
LOG_CONS |
Позволяет выводить сообщения на консоль при невозможности записи в журнал. |
Наконец, аргумент facility
позволяет определить источник сообщений:
LOG_KERN |
Указывает, что сообщения отправляются ядром. |
LOG_USER |
Указывает, что сообщения отправлены прикладным процессом (используется по умолчанию). |
LOG_MAIL |
Указывает, что инициатором сообщений является система электронной почты. |
LOG_DAEMON |
Указывает, что инициатором сообщений является системный демон. |
LOG_NEWS |
Указывает, что инициатором сообщений является система телеконференций USENET. |
LOG_CRON |
Указывает, что инициатором сообщений является система cron(1) . |
Закончив работу с журналом, следует аккуратно закрыть его с помощью функции closelog(3) :
void closelog(void);
Командный интерпретатор
Для примера интерактивного приложения, мы выбрали простейший командный интерпретатор. Данный пример позволяет продемонстрировать использование системных вызовов для порождения процесса, запуска программы и синхронизации выполнения процессов.
Функции приведенного командного интерпретатора сведены к минимуму: он распознает и выполняет несколько встроенных команд, остальной ввод он расценивает как внешние программы, которые и пытается запустить с помощью системного вызова exec(2) .
#include
#include
#include
extern char** environ;
#define CMDSIZE 80
/* Встроенные команды интерпретатора */
#define CD 1
#define ECHO 2
#define EXEC 3 ...
#define PROGRAM 1000
/* Функция, которая производит анализ строки, введенной
пользователем, выполняет подстановки и определяет,
встроенная ли это команда или программа. В качестве аргумента
функция принимает строку cmdbuf, введенную пользователем,
и возвращает имя команды/программы path и переданные ей
параметры arguments. Возвращаемое значение указывает на
внутреннюю команду или внешнюю программу, которую необходимо
запустить.*/
int parse_command(char* cmdbuf, char* path, char** arguments);
main {
charcmd[CMDSIZE];
int command;
int stat_loc;
char** args;
char cmdpath[MAXPATH];
while (1) {
/* Выведем сообщение интерпретатора */
write(1, "$ ", 2);
/* Считаем ввод пользователя и проанализируем строку */
cmdsize = read(0, cmd, CMDSIZE);
cmd[cmdsize-1] ='\0';
command = parse_command(cmd, cmdpath, args);
switch(command) {
/* Если это внутренняя команда, обработаем ее */
case (CD):
chdir(args[0]);
break;
case(ECHO):
write(1, args[0], strlen(args[0]));
break;
case(EXEC):
execve(path, args, environ);
write(2, "shell: cannot execute", 21);
break;
...
/* Если это внешняя программа, создадим дочерний процесс, который
и запустит программу */
case(PROGRAM):
pid = fork();
if (pid < 0)
write(2, "shell: cannot fork", 18);
Интервал:
Закладка: