Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

шпоры флора

.pdf
Скачиваний:
8
Добавлен:
30.03.2015
Размер:
230.8 Кб
Скачать

все они оказываются в состоянии бесконечного ожидания, т.е. в состоянии тупика. Системная тупиковая ситуация или зависание системы является следствием того, что один или более процессов находятся в состоянии тупика. Условия возникновения тупиков:

-процессы требуют предоставления им права монопольного управления ресурсами, которые им выделяются (ус-ловие взаимоисключения); -процессы удерживают за собой ресурсы, уже выделенные им, ожидая в то же время

выделения дополнительных ресурсов (условие ожидания ресурсов); -ресурсы нельзя отобрать у процессов, удерживающих их, пока эти ресурсы не будут использованы для заверше-ния работы (условие неперераспределяемости);

-существует кольцевая цепь процессов, в которой каждый процесс удерживает за собой один или более ресурсов, требующихся следующему процессу цепи (условие кругового ожидания).

44)Средства реализации виртуальной памяти , страничная переадресация

Память является важнейшим после процессора ресурсом компьютера. Поэтому ее распределению – в простейших случаях, и управлению – в современных ОС уделяется пристальнейшее внимание.

Оперативная память по своей сущности – физический объект и поэтому существенно зависит от организации работы процессора с памятью. Иначе говоря, непосредственно зависит от особенностей архитектуры процессора.

Виртуальная память требует глубоко встроенных в аппаратуру процессора внутренних средств, которые в совокупности со служебными структурами данных, создаваемыми и поддерживаемыми программно, создают видимость для отдельной программы полного владения ею всей совокупностью Так вот, адресная переадресация в виртуальной памяти аналогична некоторому

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

Каждому процессу для такой переадресации необходима своя система замены видимых для него адресных табличек на действительные физические места расположения, причем система

– незаметная самому процессу. В качестве такой системы не придумано ничего проще, чем таблицы страниц. Страницей в данной переадресации называют аналог дома в нашей вымышленной модели. Номера внутри страницы обеспечивают нумерацию ячеек, находящихся в пределах одной страницы, аналогично номерам квартир внутри дома. Таблица страниц для процесса в общем случае содержит информацию для перехода от номеров страниц, видимых процессу, к номерам реального размещения этих страниц в оперативной памяти. В простейшем, точнее упрощенном случае, строка такой таблицы с номером k содержит всего лишь номер реального размещения этой страницы в оперативной памяти. Когда для нашего примера видимый процессу обобщенный номер квартиры записывается десятичными цифрами как 007345804, то это обозначает квартиру номер 804 в доме с табличкой для процесса, обозначенной 007345. Если в таблице переадресации для данного процесса в строке с номером 007345 стоит число 017421, то в действительности за указанным обобщенным номером стоит квартира 804 в доме с физическим номером расположения 017421, т.е. физический адрес 017421804.

45) Средства реализации виртуальной памяти , стратегия подкачки страницы

Виртуальная память требует глубоко встроенных в аппаратуру процессора внутренних средств, которые в совокупности со служебными структурами данных, создаваемыми и поддерживаемыми программно, создают видимость для отдельной программы полного

владения ею всей совокупностью имеющихся ячеек физической памяти. Эта видимость называется также страничной переадресацией.

Кроме страничной переадресации, обеспечиваемой архитектурными средствами в совокупности с ОС, для функционирования виртуальной памяти используют так называемую подкачку страниц. Существо подкачки страниц в том, что часть внешней памяти используется ОС как средство временного хранения менее нужных страниц оперативной памяти, причем такое временное сохранение и восстановление информации из внешней памяти в оперативную организуется совершенно незаметно для вычислительных процессов. Практически единственное, что в этом методе (временной подмене части оперативной памяти внешней) становится заметным, так это замедление действий процесса, который ОС вынужденно приостанавливает для такого восстановления информации.

Если же в анализируемой строке таблицы страниц соответствующим битом указано, что страница не находится в физической памяти, то в ней присутствует информация, где же во внешней памяти находится содержимое этой страницы. Такая ситуация вызывает прерывание, называемое страничным прерыванием. Обрабатывая его, операционная система находит место в последовательности физических страниц, содержимое которых по ее алгоритмам можно временно вытеснить во внешнюю память. Система производит это перемещение, делает изменение в той строке таблицы страниц, которая ранее описывала вытесненное содержимое (возможно в таблице страниц другого процесса). Затем она переносит нужное содержимое страницы из внешней памяти в выбранную страницу и корректирует исходную строку таблицы страниц. По завершении прерывания вычислительный процесс возвращается к началу выполнения той исходной команды, которую начали рассматривать. Со второй попытки выполнения той же команды уже обнаруживается конкретное значение физической страницы, куда требуется доступ, и обращение осуществляется, как описано выше.

Виртуальная память позволяет выполнять программы, размер которых значительно больше размера имеющейся физической памяти. Это достигается за счет того, что из исходного файла в оперативную память переносятся только те страницы, которые действительно необходимы на текущий момент. Остальная часть исходного файла используется путем подкачки страниц по действительному запросу на них, причем часть ранее используемых страниц обычным образом вытесняется в свопинг-файл или отмечается как неизменно присутствующая в области хранимого исполняемого файла.

46)Системы распределения памяти в лине

Кроме незаметного для выполняемой программы использования виртуальной памяти, современные ОС содержат средства явного получения заказываемых объемов памяти. Операционные системы содержат системные средства, которые позволяют запрашивать для работы программы дополнительные области данных, причем для последующего доступа к этим областям системная функция возвращает значение указателя, которое может быть запомнено в именованном указателе.

Проще всего такие средства организованы в Unix. Здесь имеются всего четыре системные функции, связанные с выделением и распределением оперативной памяти, называемые malloc, free, calloc и realloc. Первая из них имеет прототип

void* malloc(size_t nbytes).

Единственным аргументом этой функции служит число байтов в запрашиваемой области данных, а возвращается указатель на не детализированный тип данных. При невозможности выделить операционной системой заданный объем памяти, эта функция возвращает нулевой указатель (NULL).

Как только запрошенная функцией malloc() область памяти становится ненужной программе, настоятельно рекомендуется отдать приказ об ее освобождении. Для этого освобождения предназначена функция с именем free. Она имеет прототип

void free(void* ptr),

Функция calloc имеет прототип

void* calloc(size_t nelem, size_t nbytes)

и позволяет выделять область данных для размещения массива из nelem элементов, каждый из которых занимает nbytes байтов.

Наконец последняя из перечисленных функций имеет прототип void* realloc(void* oldptr, size_t newsize).

Она используется для изменения размера дополнительной области памяти, ранее запрошенной у ОС и выделенной ею. При выполнении этой функции исходная область памяти может быть перемещена операционной системой в новое положение, и возвращаемое значение уже не будет совпадать со старым значением oldptr.

47) Системные функции распределения памяти в окнах

В соврем-х архитектурах доступ к страницам памяти ограничивается правами доступа как минимум: чтение и/или запись, доступ для выполнения.

W: выделение ОП включает 2 этапа: 1.to reserve построение таблиц страниц для заданного диапазона адресов; 2.to commit задействовать память,ввести в использ-е. Происходит действительное выделение памяти с отметками (за-несением слов) в табл. страниц. Для обоих действий общая ф-ия, она возвращает адрес: VirtualAlloc(void *adr, DWORD size, DWORD type, DWORD protect); adr – желаемый адрес начала блока или NULL, size – размер, type – тип операции(MEM_RESERVE,MEM_COMMIT), protectPAGE_READONLY,PAGE_READWRITE.

Обратная ф-ия: VirtualFree(void *adr, DWORD size, DWORD type); type – MEM_DECOMMIT, MEM_RELEASE.

48)Совместное использование оперативной памяти в windows

Всостав всех современных ОС включены средства использования памяти для взаимодействия независимых процессов. Основой этих средств является разделяемая память, сами средства представляют набор системных функций использования этой памяти, а на более детальном уровне – и информационные средства описания этой памяти.

Воперационной системах Windows для организации обмена через разделяемую память применяются функции, имеющие более универсальное назначение и относящиеся к отображению файлов на виртуальное адресное пространство. Основная из этих функций создает именованный или неименованный объект отображения в памяти и имеет прототип HANDLE CreateFileMapping(HANDLE hFile, SECURITY_ATTRIBUTES *pFileMappingAttributes, DWORD protect, DWORD MaxSizeHigh, DWORD MaxSizeLow, CTSTR *pName).

Базовый адрес разделяемой памяти получается для использования с помощью функции, имеющий прототип

void* MapViewOfFile(HANDLE hFileMappingObject, DWORD DesiredAccess, DWORD OffsetHigh, DWORD OffsetLow, DWORD size),

которая и возвращает требуемый базовый адрес памяти или NULL при невозможности выполнения.

Здесь первый параметр должен быть взят от предыдущего вызова функции CreateFileMapping, предоставляющего хэндл объекта отображения. Третий и четвертый аргументы этой функции совместно задают 64-битное смещение внутри виртуальной области памяти, созданной вызовом функции CreateFileMapping.

После завершения использования разделяемой памяти для освобождения уже ненужных ресурсов следует вызывать функцию UnmapViewOfFile, имеющую прототип

BOOL UnmapViewOfFile( void* pBaseAddress),

передав ей в качестве аргумента базовый адрес разделяемой памяти. Кроме того, в общем случае следует закрыть хэндл объекта отображаемой памяти с помощью функции CloseHandle.

49)Совместное использвование оперативной памяти в лине

В ОС Unix разделяемая память находится под непосредственным управлением ядра, которое содержит таблицу описания областей разделяемой памяти. Каждая из областей обозначается в этой таблице целочисленным идентификатором (а не текстовым именем, как в других ОС). Кроме того, каждая такая область описывается в этой таблице атрибутами доступа и размером. Области разделяемой памяти относятся к адресному пространству ядра ОС. Доступ к разделяемой памяти со стороны процесса осуществляется в два этапа. На первом из них получается хэндл области памяти, причем на этом этапе либо открывается доступ к уже имеющейся в ОС области памяти, либо такая область создается операционной системой. На втором этапе процесс подключается к разделяемой области (to attach), используя ранее полученный хэндл.

Для получения разделяемой памяти предназначена функция с прототипом int shmget(key_t key, int size, int flag),

возвращающая при удачном выполнении целочисленное значение требуемого идентификатора.

Для подключения процесса к запрошенной ранее области разделяемой памяти служит функция с прототипом

void* shmat(int shmid, void* addr, int flag),

Для отсоединения разделяемой памяти должна использоваться функция с прототипом int shmdt(void* addr),

аргументом которой является адрес, ранее полученный от функции shmat. При успешном выполнении она возвращает 0, а при неудаче -1.

Кроме рассмотренных базовых функций для разделяемой памяти, в Unix имеется функция расширенного управления разделяемой памятью с прототипом

int shmctl(int shmid, int cmd, struct shmid_ds *buf).

При использовании разделяемой памяти в Linux программисту предоставляется очень удобное системное средство – команда ipcs. Для получения информации о разделяемой памяти эту команду следует вызвать с опцией m, так что весь вызов имеет вид

ipcs -m

Эта команда выводит информацию о присвоенном ключе-идентификаторе, идентификаторе области памяти, владельце, размере и правах доступа к ней.

50)Структуры файловых систем для пользователя

ФС подразделяются на использующие и на не использующие обозначения логических дисков. FAT, NTFS и HPFS используют логические диски, а ФС для Unix логических дисков не используют. Применение логических дисков заметно упрощает для пользователя обозначения файлов: можно указать нахождение файла на логическом диске, где этот файл находится. В ФС с логическими дисками внешняя структура ФС описывается в виде дерева.

ВОС, использующих логические диски принято обозначать их одной латинской буквой, за которой символ двоеточие. Последовательность каталогов от корневого узла к данному файлу называется путь (path). В FAT, NTFS и HPFS разделителем в такой последовательности каталогов служит символ \. Все файлы имеют атрибуты доступа. В системах FAT, HPFS и NTFS для обслуживания таких атрибутов служит команда ATTRIB. Аргументом команды может быть имя отдельного файла и задание совокупности файлов. В простейшей форме эта команды выводит атрибуты, обозначаемые символами S, H, R, A (System, Hidden, ReadOnly, Archive).

ВUNIX все файлы собраны в одно дерево, включает три разновидности объектов: обычные файлы, каталоги и специальные файлы. Специальные файлы соответствуют устройствам компьютера: реальным или виртуальным. Дерево внешней структуры ФС Unix имеет единственный корень, обозначаемый /. Этот корень является корне-вым каталогом, перечисляющим каталоги следующего уровня. Любой каталог, отличный от корневого, может

содержать любое число обычных файлов и каталогов следующего уровня. В ФС Unix символом разделения в обозначении последовательности каталогов является прямая разделительная черта /. В Unix вместо атрибутов используются характеристики доступа для трех категорий пользователей: самого владельца (u), для членов его группы (g) и всех остальных, обозначаемых символом o (others). Для каждой категории можно задать три типа доступа: по чтению (r), по записи (w) и по выполнению (x).

53)Програмный опрос файловой системы Окна

Воперационных системах типа Windows разработчики включили проверку условия для имени файла в действия соответствующей системной функции. В этой ОС основных функций, работающих с содержимым каталогов, – две: функция поиска первого файла по задаваемому условию и функция поиска следующего файла по тому же условию. Само условие задается как метанотация, т.е. записью совокупности файлов с помощью метасимволов * и ? в соответствующем аргументе имени файла. Использование этих метасимволов полностью совпадает с традиционным их применением в командах операционной системы, восходящим к правилам командного интерпретатора Unix.

ВWindows для поиска первого файла в каталоге служит функция с прототипом HANDLE FindFirstFile(char *metaname, WIN32_FIND_DATA *FindFileData),

Для поиска следующих файлов, удовлетворяющих той же метанотации, что была задана при выполнении функции FindFirstFile, в Windows служит функция с прототипом

BOOL FindNextFile(HANDLE hFindFile, WIN32_FIND_DATA *FindFileData),

Последняя функция возвращает значение TRUE, если находит очередной файл в текущем каталоге, удовлетворяющий метанотации, в противном случае она возвращает значение FALSE.

Взавершение работы с каталогом должна вызываться функция с прототипом

BOOL FindClose(HANDLE hFindFile),

которая закрывает хэндл, ранее полученный от функции FindFirstFile.

Для вспомогательных действий по переустановке текущего каталога предназначена в Windows функция с прототипом

BOOL SetCurrentDirectory(char *PathName)), а также функция с прототипом

DWORD GetCurrentDirectory(DWORD BufferSize, char *Buffer),

которая позволяет запомнить в символьном массиве полное имя текущего каталога.

54)Линь

В ОС Unix операции с каталогом строятся подобно операциям с типизированными файлами, используемыми в Паскале, а именно, вводится указатель на структуру данных, описывающую каталог. Эта структура описана в заголовочном файле dirent.h и имеет имя DIR. Указатель на эту структуру данных используется для получения значения от функции opendir, имеющей прототип

DIR* opendir(char *dirname),

Дальнейшие действия выполняются системной функцией с прототипом struct dirent *readdir(DIR* dirptr),

с аргументом, полученным от предыдущей функции. Каждое выполнение вызова readdir() возвращает указатель на содержимое структуры типа dirent, содержащей информацию об очередном элементе каталога. Эта структура данных описана также в заголовочном файле dirent.h. В последней структуре два основных поля, которые заданы в ней как

ino_t d_ino;

/* Номер индексного дескриптора */

char d_name[ ];

/* Имя файла, заканчивающегося нулевым байтом*/

При использовании этих полей каталога следует иметь в виду, что нулевое значение поля d_ino вполне возможно у используемого каталога и обозначает неиспользуемую запись в каталоге (обычно по причине удаления информации о файле из данного каталога).

После окончания использования указателя на каталог, полученный от функции opendir(), следует выполнить закрытие доступа к каталогу и освобождение ресурсов вызовом функции с прототипом

int closedir(DIR* dirptr),

Вспомогательной функцией работы с каталогами служит функция, описываемая прототипом void rewinddir(DIR* dirptr),

которая позволяет вернуться к началу каталога с целью чтения его опять с самого начала.

55)Получение информации об ошибках выполнения системной функции Окна

Для получения кода ошибки в MS Windows программисту приходится принимать немалые дополнительные уси-лия. Если по возвращаемому значению системной функции определяется, что ошибка есть, следует немедленно вызывать специальную функцию GetLastError(), которая возвращает последнюю ошибку, возникшую в ходе вы-полнения программы (точнее нити программы). Собственно коды ошибок, общие для всех системных функций, содержатся в заголовочном файле WinError.h. Отличительной и не очень приятной особенностью MS Windows является отсутствие информации о возможных кодах ошибки для конкретных функций. Если требуется распо-знавание вида ошибки при автоматическом выполнении программы, то разработчики этой ОС предлагают для использования специальную функцию FormatMesssage, в конечном счете эта функция делает почти то же самое, что и функция strerror в Unix, но сложность использования функции FormatMessage неизмеримо больше. Прежде всего она имеет прототип len=FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,

NULL, k, // k - номер ошибки, возвращенный функцией GetLastError(), MAKELANGID(LANG_NEUTRAL, SUB-LANG_DEFAULT), txtmess, sizeof(txtmess), NULL); Главным по значению является третий её аргумент dwMessageld, который и задает распознаваемый код ошибки, адрес буфера для текста задается в аргументе IpBuffer, а его размер в аргументе nSize. Важным в применении яв-ляется и первый аргумент, который дает возможность использовать не только системные, но и пользовательские коды ошибок. Для системных ошибок в аргументе dwFlags должно присутствовать логическое слагаемое FORMAT_MESSAGE_FROM_SYSTEM. dwLanguageld обеспечивает Многоязыковую поддержку сообщений.

56)Линь

Наиболее традиционно эта проблема решается в Unix. Большинство системных функций Unix имеют вид

int имяфункции(список_аргументов),

возвращая в качестве основного значения целое число. Это число может нести значение, определяющее результат действия функции, но одно из значений (обычно -1), зарезервировано за условным кодом ошибки.

Другой формой контроля ошибок в Unix является специальная переменная errno. Для основных функций операционной системы Unix код ошибки неявно заносится в эту специальную глобальную переменную, описанную в заголовочном файле errno.h. Такой прием дает принципиальную возможность анализировать значение этой переменной после обращения к системной функции. Но делать это следует сразу же после системного вызова, так как следующий системный вызов, в свою очередь, изменяет эту переменную. Практическое использование значений переменной ошибок errno достигается с помощью вспомогательных функций perror() и strerror(). Первая из них имеет прототип

void perror(const char *s), а вторая имеет прототип char *strerror(int errnum).

Вторая функция возвращает указатель на текст, описывающий ошибку, а первая

непосредственно отображает в стандартном потоке ошибок этот текст, причем предваряемый любой пользовательской текстовой информацией, которая содержится в аргументе s.

57)Групповое выполнение и фоновый запуск команд в командных оболочках

Групповое выполнение:

В командной строке Windows NT/2000/XP можно использовать специальные символы, которые позволяют вво-дить несколько команд одновременно и управлять работой команд в зависимости от результатов их выполнения. С помощью таких символов условной обработки можно содержание небольшого пакетного файла записать в од-ной строке и выполнить полученную составную команду.

Используя символ амперсанда &, можно разделить несколько утилит в одной командной строке, при этом они будут выполняться друг за другом. Например, если набрать команду DIR & PAUSE & COPY /? и нажать клавишу <Enter>, то вначале на экран будет выведено содержимое текущего каталога, а после нажатия любой клавиши — встроенная справка команды COPY.

Символ ^ позволяет использовать командные символы как текст, то есть при этом происходит игнорирование значения специальных символов. Например, если ввести в командной строке ECHO Абв & COPY /?

и нажать клавишу <Enter>, то произойдет выполнение подряд двух команд: ECHO Абв и COPY /? (команда ECHOвыводит на экран символы, указанные в командной строке после нее).

58) В-ВВ конвеер юниксы

Понимание концепции ввода-вывода в UNIX требуется как для самих атак, так и для успешной защиты от них.

Любую программу можно рассматривать как «черный ящик» с входом и выходом. Это справедливо для большинства консольных приложений MS-DOS и Windows 9x/Windows NT, но графические приложения помимо результатов своей работы выводят множество вспомогательной информации, и в определенных ситуациях оказываются бесполезными. Например, все серверные приложения должны по возможности минимизировать обмен с пользователем, посылая и принимая только полезную информацию, а обличить ее в красивый интерфейс можно и на клиентской стороне.

Разработчики UNIX значительно облегчили написание модульных программ, унифицировав систему ввода-вывода. С любым устройством стало возможно обращаться точно так, как с файлом, в частности читать и писать в него. Поэтому, результат работы одной программы может быть использован другой или выведен на экран.

Например, программу копирования файлов “copy” (MS-DOS) ничуть ни хуже использовать для создания новых файлов и вывода их содержимого на экран. Для этого достаточно вспомнить, что с клавиатурой и терминалом (объединенных в MS-DOS в устройстве под именем ‘con’) можно обращаться точь-в-точь как с обычным файлом. Доказывает это утверждение следующий эксперимент:

copy con myfile

Hello, World!

^Z

1 файлов скопировано

copy myfile con

Hello, World!

1 файлов скопировано

Начинающим, вероятно, следует пояснить – символ <Ctrl-Z> указывает программе на завершение ввода и конец файла. В самом файле он отсутствует.

В качестве другого примера используем коротенькую демонстрационную программу, написанную на языке Си – “/SRC/io.c”, исходный текст которой приведен ниже (для наглядности никакие проверки не выполняются).

#include <stdio.h>

int main(int argc, char *argv[])

return 0;

}

Она читает одну строку из файла, переданного в качестве первого аргумента командной строки, и записывает во второй ASCII коды символов в шестнадцатеричном представлении. Например, так:

io.exe con con

Hello, Sailor!

0x48

0x65

0x6C

0x6C

0x6F

0x2C

0x20

0x53

0x61

0x69

0x6C

0x6F

0x72

0x21

0xA

Характерная особенность этой (да и многих других) программ – использование клавиатуры и терминала для приема и отображения информации. Но постоянно указывать ‘con con’ слишком утомительно, гораздо лучше заранее назначить устройства ввода-вывода по умолчанию.

В стандартной библиотеке языка Си для этой цели используются файловые манипуляторы stdin и stdout, связанные со стандартными устройствами ввода и вывода соответственно. Модернизированный вариант программы может выглядеть так (на диске он находится под именем “/SRC/iostd.c”):

#include <stdio.h>

int main(int argc, char *argv[])

return 0;

}

Но как в этом случае заставить программу выводить результаты работы в файл, а не терминал? Стандартный ввод-вывод выгодно отличается возможностью направить его куда угодно, указав в командной строке специальный символ “>” для вывода и “<” для ввода. Например, используем ранее созданный файл myfile и выведем результат работы iostd в файл “out.txt”. Это можно сделать следующим образом:

iostd.exe <myfile >out.txt

copy out.txt con

0x48

0x65

0x6C

0x6C

0x6F

0x2C

0x20

0x53

0x61

0x69

0x6C

0x6F

0x72

0x21

0xA

1 файлов скопировано

Да, это работает! Но как? Командный интерпретатор при запуске анализирует командную строку и если обнаруживает символы перенаправления ввода-вывода, открывает соответствующие файлы и связывает с ними потоки ввода-вывода.

Перенаправление ввода-вывода полезная штука, но зачастую слишком уж уязвимая для атак. Рассмотрим следующий код (расположенный на диске под именем “/SRC/iohack.c”), часто встречающийся в UNIX-приложениях.

#include <stdio.h>

main()

}

Программа запрашивает у пользователя строку и выводит ее на экран. Но, если указать знак перенаправления потока ввода, на экран выдастся содержимое запрашиваемого файла! Например:

iohack.exe

$Hello!

Hello!

iohack.exe

$<myfile

Hello, Sailor!

С одной стороны, поддержка приложением перенаправления ввода-вывода очень удобна и облегчает работу с компьютером (в самом деле, зачем вводить текст вручную, если его можно взять из файла?), но… часто приводит к последствиям никак не запланированными разработчиком[1].

Приведенный выше пример, запущенный в среде UNIX, встретив конструкцию “</etc/passwd” выдаст на экран содержимое файла паролей, или любого другого файла который будет запрошен. С первого взгляда ничего страшного в этом нет, – программа наследует все привилегии пользователя и получает доступ к тем, и только к тем, файлам, которые пользователь мог бы просмотреть и без помощи этой программы, скажем, командой “cat”.

Но все безоблачно лишь на первый взгляд. В UNIX есть два типа процессов – наследующие права пользователя и исполняющиеся от имени системы. Примером последних может служить почтовый демонSendMail, обычно исполняющийся с наивысшими привилегиями. Ранние версии поддерживали перенаправление ввода-вывода и позволяли приаттачить к письму любой файл, даже недоступный простому пользователю.

Разумеется, SendMail не одинок, и подобные ошибки допущены во множестве приложений, щедро разбросанных по серверам. Часто для их поиска даже не требуется кропотливого изучения исходных текстов программы – достаточно во всех вводимых строках (или полях заголовка) подставить символ “<” и посмотреть на реакцию программы – нет-нет, да повезет! Однако возможности перенаправления ввода-вывода очень ограничены. Рассмотрим это на

следующем примере, – пусть требуется получить отсортированный в обратном порядке список файлов текущей директории. Команда ‘ls’ не предоставляет такого сервиса, поэтому придется воспользоваться утилитой ‘sort’ Сперва сохраним результат работы команды ‘ls’ (или dir в MS-DOS) в файле temp. Затем используем его в качестве входного потока данных утилиты ‘sort’, запушенной с ключом ‘-r’ для задания обратного порядка сортировки.

$ ls >temp

$ sort -r <temp

temp

sioux.pl

passwd

iohack.o

iohack.c

index_hack.htm

demos.txt

bomb.pl

attack2.htm

Да, это работает, но требует создания лишнего файла на диске и в целом недостаточно удобно. А нельзя ли связать стандартный вывод одной программы со стандартным вводом другой? Можно! И такая конструкция называется конвейер или труба (от английского pipe). Для создания конвейера необходимо использовать символ “|”, разделяющий запускаемые программы следующим образом: “программа 1 параметры | программа 2 параметры | программа 3 параметры”. Разумеется, стандартный ввод первой программы в цепочке и стандартный вывод последней могут быть перенаправлены с помощью символов “<” и “>” соответственно (результат попытки перенаправления остальных непредсказуем, и обычно разрывает цепочку конвейера).

Интереснее проследить, как происходит взаимодействие процессов и передача данных по конвейеру. Конвейер – сути дела тот же файл, но скрытый от пользователя, построенный по принципу FIFO (от английскогоFirst Input First Output – первый пришел – первым и уйдешь). Так, запись в конвейер, из которого никто не читает, рано или поздно вызывает его переполнение (а размер буфера обычно порядка четырех килобайт) и приводит к блокировке процесса-писателя, до тех пор, пока хотя бы один байт из конвейера не будет прочитан. Точно так, попытка чтения из пустого конвейера приводит к остановке процесса-читателя до тех пор, пока в нем не окажется хотя бы один байт.

Рисунок 012.txt Схематическое изображения конвейера

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

$ ls | sort -r

sioux.pl

passwd

iohack.o

iohack.c

index_hack.htm

demos.txt

bomb.pl

attack2.htm

Не правда ли намного проще и элегантнее? Между прочим, конвейеры поддерживаются не исключительно одной UNIX, – не хуже с ними справляется и старушка MS-DOS. Доказывает это эксперимент, приведенный ниже:

dir /b | sort /r

sioux.pl

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]