Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
113: }
114: endutent();
115: }
116:
117: int main(int argc, const char **argv) {
118: char * id = NULL, *line = NULL;
119: int show_utmp = 1, show_wtmp = 0;
120: int c;
121: poptContext optCon;
122: struct poptOption optionsTable[] = {
123: {"utmp", 'u', POPT_ARG_NONE|POPT_ARGFLAG_XOR,
124: &show_utmp, 0,
125: "переключить просмотр содержимого файла utmp", NULL},
126: { "wtmp", 'w', POPT_ARG_NONE | POPT_ARGFLAG_XOR,
127: &show_wtmp, 0,
128: "переключить просмотр содержимого файла wtmp", NULL},
129: {"id", 'i', POPT_ARG_STRING, &id, 0,
130: "показать записи процесса для заданного идентификатора inittab",
131: "" },
132: {"line", 'l', POPT_ARG_STRING, &line, 0,
133: "показать записи процесса для заданной строки устройства",
134: "" },
135: POPT_AUTOHELP
136: POPT_TABLEEND
137: };
138:
139: optCon = poptGetContext("utmp", argc, argv, optionsTable, 0);
140: if ((c = poptGetNextOpt(optCon)) < -1) {
141: fprintf(stderr, "%s:%s\n",
142: poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
143: poptStrerror(c));
144: return 1;
145: }
146: poptFreeContext(optCon);
147:
148: if (id && line)
149: fprintf(stderr, "Невозможно выбирать сразу по идентификатору и строке,"
150: "выбор по строке\n");
151:
152: if (show_utmp)
153: print_file(_PATH_UTMP, id, line);
154: if (show_utmp && show_wtmp)
155: printf("\n\n\n");
156: if (show_wtmp)
157: print_file(_PATH_WTMP, id, line);
158:
159: return 0;
160: }
16.2. Обзор termios
Все манипуляции tty осуществляются с помощью одной структуры, struct termios
, а также нескольких функций, определенных в заголовочном файле . Из этих функций широко применяются только шесть. Когда не нужно устанавливать скорость передачи данных по линии, используются только две наиболее важных функции — tcgetattr()
и tcsetattr()
.
#include
struct termios {
tcflag_t c_iflag; /* флаги режима ввода */
tcflag_t c_oflag; /* флаги режима вывода */
tcflag_t c_cflag; /* флаги управляющего режима */
tcflag_t c_lflag; /* флаги локального режима */
cc_t c_line; /* дисциплина линии связи */
cc_t c_cc[NCCS]; /* управляющие символы */
};
int tcgetattr(int fd, struct termios * tp);
int tcsetattr(int fd, int oact, struct termios * tp);
Почти в каждом случае программы должны использовать tcgetattr()
для получения текущих установок устройства, модифицировать эти установки, а затем применять tcsetattr()
для активизации модифицированных установок. Многие программы также сохраняют копии оригинальных установок и восстанавливают их перед завершением. В общем случае, следует модифицировать только интересующие вас установки; изменение других установок может усложнить работу пользователей с необычными системными конфигурациями (или сбоями в вашем коде).
Вызов tcsetattr()
может не принять на обработку выбранные вами установки; разрешено игнорировать произвольные установки. Если оборудование просто не поддерживает установку, tcsetattr()
игнорирует ее, а не возвращает ошибку. Если вам небезразлично воздействие, оказываемое установкой, следует использовать tcgetattr()
после tcsetattr()
и проверить, оказало ли воздействие внесенное вами изменение.
Для получения установок устройства tty необходимо открыть устройство и передать файловый дескриптор tcgetattr()
. Это вызывает проблемы с некоторыми устройствами tty; некоторые обычно можно открыть лишь один раз с целью предотвращения конфликта устройств. К счастью, передача флага O_NONBLOCK
в open()
вызывает его немедленное открытие и предотвращает блокирование любых операций. Однако все равно можно предпочесть блокирование read()
; в таком случае используйте fcntl()
для отключения режима O_NONBLOCK
перед тем, как появится возможность читать или записывать в него.
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
Четыре флага termios
контролируют четыре отдельных части управления вводом и выводом. Флаг входных данных, с_iflag
, определяет, каким образом интерпретируются и обрабатываются принятые символы. Флаг выходных данных, c_oflag
, определяет, каким образом интерпретируются и обрабатываются символы, записываемые вашим процессом в tty. Управляющий флаг, c_cflag
, определяет характеристики последовательного протокола устройства и полезен лишь для физических устройств. Локальный флаг, c_lflag
, определяет, каким образом символы собираются и обрабатываются перед отправкой на обработку выходных данных. На рис. 16.1 показана упрощенная схема того, какое место занимает каждый флаг в общей схеме обработки символов.

Рис. 16.1. Упрощенная схема обработки tty
Сначала мы продемонстрируем способы применения termios
, а затем представим короткую справку о нем.
16.3. Примеры использования termios
16.3.1. Пароли
Самой распространенной причиной модификации установок termios
является чтение пароля без эхо-контроля символов. Для этого следует отключить локальное эхо во время чтения пароля. Ваш код должен выглядеть следующим образом:
struct termios ts, ots;
Первая структура хранит оригинальные установки для восстановления, а вторая является копией для модификации.
tcgetattr(STDIN_FILENO, &ts);
Обычно пароли читаются со стандартного устройства ввода.
ots = ts;
Сохраните копию оригинальных установок termios
, чтобы позже восстановить их.
ts.c_lflag &= ~ECHO;
ts.c_lflag |= ECHONL;
tcsetattr(STDIN_FILENO, TCSAFLUSH, fits);
Отключите эхо-контроль символов (кроме символов новой строки) после завершения обработки всех выходных данных. (Первая l
в c_lflag
означает локальную (local) обработку.)
read_password();
Теперь вы читаете пароль. Это может быть простой вызов fgets()
или read()
, либо же более сложная обработка, в зависимости от режима tty (неформатируемый режим или режим обработки) и от требований программы.
tcsetattr(STDIN_FILENO, TCSANOW, &ots);
Это немедленно восстанавливает исходные установки termios
. (Остальные опции объясняются позже, в справочном разделе далее в главе.)
Полный код программы-примера, readpass
, показан ниже.
1: /* readpass.с */
2:
3: #include
4: #include
5: #include
6: #include
7:
8: int main (void) {
9: struct termios ts, ots;
10: char passbuf[1024];
11:
12: /* получить и сохранить текущие настройки termios */
13: tcgetattr(STDIN_FILENO, &ts);
14: ots = ts;
15:
16: /* изменить и установить новые настройки termios */
17: ts.c_lflag & = ~ECHO;
18: ts.c_lflag |= ECHONL;
19: tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);
Интервал:
Закладка: