неканонический режим и отсутствие эха, не работающий с каналом

#c #linux #terminal #pipe

#c #linux #терминал #канал

Вопрос:

Недавно я пытаюсь написать простую версию Linux command more . Для того, чтобы сделать это, мне нужно ввести неканонический режим и отсутствие эха в терминале, чтобы я получал ввод сразу после нажатия клавиши, а терминал не отображал символ, который я ввожу.

Я сделал это, поступив таким образом:

   // set the terminal mode
  struct termios tm;
  tcgetattr(STDIN_FILENO, amp;old);
  tm = old;
  tm.c_lflag amp;= ~(ICANON | ECHO);
  tm.c_cc[VMIN] = 1;
  tm.c_cc[VTIME] = 0;
  tcsetattr(STDIN_FILENO, TCSADRAIN, amp;tm);
  

Это работает, когда я использую аргументы типа

 more test_file
  

Но когда я попытался выполнить канал more с помощью другой команды, такой как

 ls /bin | more
  

Терминал возвращается в канонический режим и режим эха. Почему это происходит?

Комментарии:

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

2. Вы не проверили результаты системных вызовов, и они завершились неудачей, вероятно, из-за ошибки ENOTTY.

3. man7.org/linux/man-pages/man3/ctermid.3.html

4. @Someprogrammerdude И как именно я могу это сделать?

Ответ №1:

Вообще говоря, такие вещи, как more ожидаются для чтения из stderr (или иногда, /dev/tty но stderr работает лучше). Вместо этого вы включаете терминал stdin . Это работает не так хорошо.

Комментарии:

1. В программе я считываю нажатие клавиши из /dev/tty . Что мне делать?

2.В программе я считываю нажатие клавиши из /dev/tty . Что мне делать?

3. @Rivers Shall: очевидно, что тогда вы также должны использовать tcgetattr и tcsetattr в вашем дескрипторе / dev / tty. Смотрите функцию fileno.