Читаем Linux API. Исчерпывающее руководство полностью

• При возобновлении работы, инициированном сигналом SIGCONT, обработчик повторно сохраняет текущие параметры терминала в переменной userTermios , так как за это время пользователь мог их поменять (например, с помощью команды stty). Затем обработчик возвращает терминал к состоянию, которое требуется для работы программы (ourTermios) .

Листинг 58.4. Демонстрация режима без обработки и cbreak

tty/test_tty_functions.c

#include

#include

#include

#include "tty_functions.h" /* Объявление ttySetCbreak() и ttySetRaw() */

#include "tlpi_hdr.h"

static struct termios userTermios;

/* Параметры терминала, определенные пользователем */

static void /* Общий обработчик: восстанавливает параметры tty и завершается */

handler(int sig)

{

if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &userTermios) == -1)

errExit("tcsetattr");

_exit(EXIT_SUCCESS);

}

static void /* Обработчик для SIGTSTP */

tstpHandler(int sig)

{

struct termios ourTermios; /* Для сохранения параметров нашего терминала */

sigset_t tstpMask, prevMask;

struct sigaction sa;

int savedErrno;

savedErrno = errno; /* Здесь можно было бы изменить 'errno' */

/* Сохраняем текущие параметры терминала, возвращаем терминал

к состоянию, в котором он был на момент запуска программы */

if (tcgetattr(STDIN_FILENO, &ourTermios) == -1)

errExit("tcgetattr");

if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &userTermios) == -1)

errExit("tcsetattr");

/* Устанавливаем для SIGTSTP действие по умолчанию, посылаем сигнал

еще раз и разблокируем его, чтобы программа могла остановиться */

if (signal(SIGTSTP, SIG_DFL) == SIG_ERR)

errExit("signal");

raise(SIGTSTP);

sigemptyset(&tstpMask);

sigaddset(&tstpMask, SIGTSTP);

if (sigprocmask(SIG_UNBLOCK, &tstpMask, &prevMask) == -1)

errExit("sigprocmask");

/* Выполнение возобновляется после SIGCONT */

if (sigprocmask(SIG_SETMASK, &prevMask, NULL) == -1)

errExit("sigprocmask"); /* Повторно блокируем SIGTSTP */

sigemptyset(&sa.sa_mask); /* Заново устанавливаем обработчик */

sa.sa_flags = SA_RESTART;

sa.sa_handler = tstpHandler;

if (sigaction(SIGTSTP, &sa, NULL) == -1)

errExit("sigaction");

/* С момента остановки программы пользователь мог изменить параметры

терминала; сохраняем параметры, чтобы позже их восстановить */

if (tcgetattr(STDIN_FILENO, &userTermios) == -1)

errExit("tcgetattr");

/* Восстанавливаем наши параметры терминала */

if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &ourTermios) == -1)

errExit("tcsetattr");

errno = savedErrno;

}

int

main(int argc, char *argv[])

{

char ch;

struct sigaction sa, prev;

ssize_t n;

sigemptyset(&sa.sa_mask);

sa.sa_flags = SA_RESTART;

if (argc > 1) { /* Используем режим cbreak */

 if (ttySetCbreak(STDIN_FILENO, &userTermios) == -1)

errExit("ttySetCbreak");

/* В режиме cbreak специальные символы терминала могут генерировать сигналы.

Перехватываем их, чтобы откорректировать режим терминала. Устанавливаем

обработчики только для сигналов, которые не игнорируются. */

 sa.sa_handler = handler;

if (sigaction(SIGQUIT, NULL, &prev) == -1)

errExit("sigaction");

if (prev.sa_handler!= SIG_IGN)

if (sigaction(SIGQUIT, &sa, NULL) == -1)

errExit("sigaction");

if (sigaction(SIGINT, NULL, &prev) == -1)

errExit("sigaction");

if (prev.sa_handler!= SIG_IGN)

if (sigaction(SIGINT, &sa, NULL) == -1)

errExit("sigaction");

 sa.sa_handler = tstpHandler;

if (sigaction(SIGTSTP, NULL, &prev) == -1)

errExit("sigaction");

if (prev.sa_handler!= SIG_IGN)

if (sigaction(SIGTSTP, &sa, NULL) == -1)

errExit("sigaction");

} else { /* Используем режим без обработки */

 if (ttySetRaw(STDIN_FILENO, &userTermios) == -1)

errExit("ttySetRaw");

}

sa.sa_handler = handler;

if (sigaction(SIGTERM, &sa, NULL) == -1)

errExit("sigaction");

setbuf(stdout, NULL); /* Отключаем буферизацию стандартного вывода */

for (;;) { /* Считываем и отображаем стандартный ввод */

n = read(STDIN_FILENO, &ch, 1);

if (n == -1) {

errMsg("read");

break;

}

if (n == 0) /* Может произойти после отключения терминала */

break;

 if (isalpha((unsigned char) ch)) /* Буквы — > нижний регистр */

putchar(tolower((unsigned char) ch));

else if (ch == '\n' || ch == '\r')

putchar(ch);

else if (iscntrl((unsigned char) ch))

printf("^%c", ch ^ 64); /* Выводим Ctrl+A как ^A и т. д. */

else

putchar('*'); /* Остальные символы выводятся как '*' */

 if (ch == 'q') /* Выходим из цикла */

break;

}

if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &userTermios) == -1)

errExit("tcsetattr");

exit(EXIT_SUCCESS);

}

tty/test_tty_functions.c

Пример запуска программы из листинга 58.4 в режиме без обработки показан ниже:

$ stty Изначально терминал находится в обычном состоянии (с обработкой)

speed 38400 baud; line = 0;

$ ./test_tty_functions

abc Вводим abc и Ctrl+J

def Вводим DEF, Ctrl+J и Enter

^C^Z Вводим Ctrl+C, Ctrl+Z и Ctrl+J

qВводим q, чтобы выйти

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных