Операционная система UNIX
Операционная система UNIX читать книгу онлайн
Книга посвящена семейству операционных систем UNIX и содержит информацию о принципах организации, идеологии и архитектуре, объединяющих различные версии этой операционной системы.
В книге рассматриваются: архитектура ядра UNIX (подсистемы ввода/вывода, управления памятью и процессами, а также файловая подсистема), программный интерфейс UNIX (системные вызовы и основные библиотечные функции), пользовательская среда (командный интерпретатор shell, основные команды и утилиты) и сетевая поддержка в UNIX (протоколов семейства TCP/IP, архитектура сетевой подсистемы, программные интерфейсы сокетов и TLI).
Для широкого круга пользователей.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Последний тип сообщений подсказывает еще одну возможность использования системного журнала — для отладки программ, особенно неинтерактивных.
Строка
logstring%merrnoФункция openlog(3) позволяет определить ряд опций ведения журнала. Она имеет следующее определение:
void openlog(char *ident, int logopt, int facility);Строка
identlogoptLOG_PID | Позволяет указывать идентификатор процесса в каждом сообщении. Эта опция полезна при журналировании нескольких демонов с одним и тем же значением ident, например, когда демоны порождаются вызовом fork(2). |
LOG_CONS | Позволяет выводить сообщения на консоль при невозможности записи в журнал. |
Наконец, аргумент
facilityLOG_KERN | Указывает, что сообщения отправляются ядром. |
LOG_USER | Указывает, что сообщения отправлены прикладным процессом (используется по умолчанию). |
LOG_MAIL | Указывает, что инициатором сообщений является система электронной почты. |
LOG_DAEMON | Указывает, что инициатором сообщений является системный демон. |
LOG_NEWS | Указывает, что инициатором сообщений является система телеконференций USENET. |
LOG_CRON | Указывает, что инициатором сообщений является система cron(1). |
Закончив работу с журналом, следует аккуратно закрыть его с помощью функции closelog(3):
void closelog(void);Командный интерпретатор
Для примера интерактивного приложения, мы выбрали простейший командный интерпретатор. Данный пример позволяет продемонстрировать использование системных вызовов для порождения процесса, запуска программы и синхронизации выполнения процессов.
Функции приведенного командного интерпретатора сведены к минимуму: он распознает и выполняет несколько встроенных команд, остальной ввод он расценивает как внешние программы, которые и пытается запустить с помощью системного вызова exec(2).
#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>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] =' '; 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); else if (pid == 0) { /* Дочерний процесс */ execve(path, args, environ);
