Операционная система UNIX
Операционная система UNIX читать книгу онлайн
Книга посвящена семейству операционных систем UNIX и содержит информацию о принципах организации, идеологии и архитектуре, объединяющих различные версии этой операционной системы.
В книге рассматриваются: архитектура ядра UNIX (подсистемы ввода/вывода, управления памятью и процессами, а также файловая подсистема), программный интерфейс UNIX (системные вызовы и основные библиотечные функции), пользовательская среда (командный интерпретатор shell, основные команды и утилиты) и сетевая поддержка в UNIX (протоколов семейства TCP/IP, архитектура сетевой подсистемы, программные интерфейсы сокетов и TLI).
Для широкого круга пользователей.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Последний тип сообщений подсказывает еще одну возможность использования системного журнала — для отладки программ, особенно неинтерактивных.
Строка
logstring
%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 <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);