Нейл Мэтью - Основы программирования в Linux
- Название:Основы программирования в Linux
- Автор:
- Жанр:
- Издательство:«БХВ-Петербург»
- Год:2009
- Город:Санкт-Петербург
- ISBN:978-5-9775-0289-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Нейл Мэтью - Основы программирования в Linux краткое содержание
В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стандартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым.
Для начинающих Linux-программистов
Основы программирования в Linux - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Дополнительные функции
Есть небольшое число дополнительных функций для управления терминалами. Они работают непосредственно с дескрипторами файлов без необходимости считывания и записывания структур типа
termios
.
#include
int tcdrain(int fd);
int tcflow(int fd, int flowtype);
int tcflush(int fd, int in_out_selector);
Функции предназначены для следующих целей:
□
tcdrain
— заставляет вызвавшую программу ждать до тех пор, пока не будет отправлен весь поставленный в очередь вывод;
□
tcflow
— применяется для приостановки или возобновления вывода;
□
tcflush
— может применяться для отказа от входных или выходных данных либо и тех, и других.
Теперь, когда мы уделили довольно много внимания структуре
termios
, давайте рассмотрим несколько практических примеров. Возможно, самый простой из них — отключение отображения при чтении пароля (упражнение 5.4). Это делается сбрасыванием флага echo
.
Упражнение 5.4. Программа ввода пароля с применение termios
1. Начните вашу программу password.с со следующих определений:
#include
#include
#include
#define PASSWORD_LEN 8
int main() {
struct termios initialrsettings, newrsettings;
char password[PASSWORD_LEN + 1];
2. Далее добавьте строку, считывающую текущие установки из стандартного ввода и копирующую их в только что созданную вами структуру типа
termios
:
tcgetattr(fileno(stdin), &initialrsettings);
3. Создайте копию исходных установок, чтобы восстановить их в конце. Сбросьте флаг
ECHO
в переменной newrsettings
и запросите у пользователя его пароль:
newrsettings = initialrsettings;
newrsettings.с_lflag &= ~ЕСНО;
printf("Enter password: ");
4. Далее установите атрибуты терминала в newrsettings и считайте пароль. И наконец, восстановите первоначальные значения атрибутов терминала и выведите пароль на экран, чтобы свести на нет все предыдущие усилия по обеспечению безопасности:
if (tcsetattr(fileno(stdin), TCSAFLUSH, &newrsettings) != 0) {
fprintf(stderr, "Could not set attributes\n");
} else {
fgets(password, PASSWORD_LEN, stdin);
tcsetattr(fileno(stdin), TCSANOW, &initialrsettings);
fprintf(stdout, "\nYou entered %s\n", password);
}
exit(0);
}
Когда вы выполните программу, то увидите следующее:
$ ./password
Enter password: You entered hello
$
Как это работает
В этом примере слово
hello
набирается на клавиатуре, но не отображается на экране в строке приглашения Enter password:
. Никакого вывода нет до тех пор, пока пользователь не нажмет клавишу .
Будьте осторожны и изменяйте с помощью конструкции
X&=~FLAG
(которая очищает бит, определенный флагом FLAG
в переменной X
) только те флаги, которые вам нужно изменить. При необходимости можно воспользоваться конструкцией X|=FLAG
для установки одиночного бита, определяемого FLAG
, хотя в предыдущем примере она не понадобилась.
Для установки атрибутов применяется действие
TCSAFLUSH
для очистки буфера клавиатуры, символов, которые пользователи вводили до того, как программа подготовилась к их считыванию. Это хороший способ заставить пользователей не начинать ввод своего пароля, пока не отключено отображение. Перед завершением программы вы также восстанавливаете первоначальные установки.
Другой распространенный пример использования структуры
termios
— перевод терминала в состояние, позволяющее вам считывать каждый набранный символ (упражнение 5.5). Для этого отключается канонический режим и используются параметры MIN
и TIME
.
Упражнение 5.5. Считывание каждого символа
Применяя только что полученные знания, вы можете изменить программу menu. Приведенная далее программа menu4.c базируется на программе menu3.c и использует большую часть кода из файла password.с, включенного в нее. Внесенные изменения выделены цветом и объясняются в пунктах описания.
1. Прежде всего, вам следует, включить новый заголовочный файл в начало программы:
#include
#include
#include
#include
char *menu[] = {
"a — add new record",
"d — delete record",
"q - quit",
NULL,
};
2. Затем нужно объявить пару новых переменных в функции
main
:
int getchoice(char *greet, char *choices[], FILE *in, FILE *out);
int main() {
int choice = 0;
FILE *input;
FILE *output;
struct termios initial_settengs, new_settings;
3. Перед вызовом функции
getchoice
вам следует изменить характеристики терминала, этим определяется место следующих строк:
if (!isatty(fileno(stdout))) {
fprintf(stderr, "You are not a terminal, OK.\n");
}
input = fopen("/dev/tty", "r");
output = fopen("/dev/tty", "w");
if (!input || !output) {
fprintf(stderr, "Unable to open /dev/tty\n");
exit(1);
}
tcgetattr(fileno(input), &initial_settings);
new_settings = initial_settings;
new_settings.c_lfag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
new_settings.c_lflag &= ~ISIG;
if (tcsetattr(fileno(input), TCSANOW, &new_settings) != 0) {
fprintf(stderr, "could not set attributes\n");
}
4. Перед завершением вы также должны вернуть первоначальные значения:
do {
choice = getchoice("Please select an action", menu, input, output);
printf("You have chosen: %c\n", choice);
} while (choice != 'q');
tcsetattr(fileno(input), TCSANOW, &initial_settings);
exit(0);
}
5. Теперь, когда вы в неканоническом режиме, необходимо проверить на соответствие возвраты каретки, поскольку стандартное преобразование CR (возврат каретки) в LF (переход на новую строку) больше не выполняется:
int getchoice (char *greet, char *choices[], FILE *in, FILE *out) {
int chosen = 0;
int selected;
char **option;
do {
fprintf(out, "Choice: %s\n", greet);
option = choices;
while (*option) {
fprintf(but, "%s\n", *option);
option++;
}
do {
selected = fgetc(in);
} while (selected == '\n' || selected == '\r');
option = choices;
while (*option) {
if (selected == *option[0]) {
chosen = 1;
break;
}
option++;
}
if (!chosen) {
fprintf(out, "Incorrect choice, select again\n");
}
} while(!chosen);
return selected;
}
Пока вы не устроите все иначе, теперь, если пользователь нажмет в вашей программе комбинацию клавиш +, программа завершится. Вы можете отключить обработку этих специальных символов, очистив флаг
ISIG
в локальных режимах. Для этого в функцию main
включается следующая строка:
Интервал:
Закладка: