Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP_term_work.doc
Скачиваний:
1
Добавлен:
17.11.2019
Размер:
251.9 Кб
Скачать

Void c_handl(int num) //обработчик sigchld

{

...

//разрешаем обработку SIGCHLD внутри функции,

//делая ее таким образом реентерабельной

sigprocmask(SIG_UNBLOCK,&cldset,0); //в некоторых системах проще использовать

//флаг SA_NODEFER при вызове sigaction()

...

}

...

//маскируем SIGTTOU для этого процесса и его потомков

sigemptyset(&cldset);

sigaddset(&cldset,SIGTTOU); //делаем маску

sigprocmask(SIG_BLOCK,&cldset,0); //устанавливаем

sigemptyset(&cldset);

sigaddset(&cldset,SIGCHLD); //маску cldset будет использовать обработчик

act.sa_handler=c_handl; //задаем адрес обработчика

act.sa_flags=0; //очищаем флаги (в этом примере - лишнее действие)

sigfillset(&act.sa_mask); //маскировать на время обработки все сигналы,

sigdelset(&act.sa_mask,SIGCHLD); //кроме самого SIGCHLD

sigaction(SIGCHLD,&act,0); //устанавливаем реакцию на SIGCHILD

//В результате все сигналы SIGCHLD будут обработаны,

//причем обработчик может быть прерван только сигналами SIGKILL,

//SIGSTOP, ну и SIGCHILD

...

4. Терминальный ввод/вывод

Процесс может производить чтение/запись и получать сигналы типа SIGINT, SIGQUIT

и SIGTSTP c управляющего терминала, если он принадлежит той же программной группе,

что и терминал. Иначе, при попытке чтения/записи процесс будет получать сигналы

SIGTTIN/SIGTTOU. По этому принципу процессы делятся на интерактивные (foreground)

и фоновые (background, или асинхронные).

Управляющий терминал вместе с открытыми для него стандартными потоками ввода/вывода

наследуется процессом от родителя.

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

ввода/вывода, скоростью передачи информации и т. п. Если аппаратура терминала

(или его эмулятор) поддерживает широкий набор возможностей по управлению

вводом/выводом, такой терминал называют интеллектуальным (smart), иначе

терминал будет простым (dumb). Обычно терминалы используют некоторый набор

соглашений (протокол) об обмене управляющей информацией с программами.

Примерами таких протоколов являются vt100 и ANSI, описанные в приложении.

Терминал с одной стороны, и его драйвер с другой, должны работать в согласованых

по основным параметрам режимах. Режим работы драйвера для конкретного терминала

можно изменить с помощью стандартного системного вызова ioctl(), передавая ему

в качестве одного из аргументов имя файла устройства. Существует также утилита

'stty' для просмотра/изменения параметров терминала из командной строки.

В некоторых системах есть упрощенный интерфейс к ioctl() - функции типа

tcgetattr(), tcsetattr().

Управляющие символы, поступающие с терминала, могут обрабатываться его

драйвером. Например, комбинации клавиш Ctrl+c, Ctrl+\ и Ctrl+z приводят к

посылке процессам, связанным с этим терминалом, сигналов SIGINT, SIGQUIT и

SIGTSTP соответственно. Генерацию сигналов можно включить/выключить, а

комбинацию символов - переопределить вызовом ioctl().

Рассмотрим конкретный пример изменения параметров драйвера терминала.

По умолчанию терминал UNIX работает в так называемом каноническом режиме,

что означает передачу символов, введенных с клавиатуры в пользовательскую

программу только после нажатия клавиши перевода строки. Если требуется ввод

символов без ожидания и какой-либо предварительной обработки, необходимо

отменить этот режим. Кроме того, драйвер автоматически посылает "эхо" ввода

на терминал, что тоже не всегда является приемлемым (например, Вы решили

реализовать в программе реакцию на нажатие функциональных клавиш). Эхо тоже

можно отменить, а там где оно необходимо, реализовать его в своей программе.

Пример: Изменение режимов терминала (протестирован под Linux 6.2).

#include <sys/types.h>

#include <unistd.h>

#include <termios.h>

#include <fcntl.h>

#include <stdio.h>

struct termios term;

tcflag_t oldflags;

main()

{

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