2017-01-09 2 views
0

У меня есть терминал работает псевдо на Linux, C, который был открыт, как показано:Использование termios() для замены EOF?

else 
{ 
    struct termios slave_orig_term_settings; // Saved terminal settings 
    struct termios new_term_settings; // Current terminal settings 

    // CHILD 
    close(fdm); 

    rc = tcgetattr(fds, &slave_orig_term_settings); 

    new_term_settings = slave_orig_term_settings; 

    new_term_settings.c_cc[VEOF] = '|'; 
    new_term_settings.c_oflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | ICRNL); 

    cfmakeraw (&new_term_settings); 

    tcsetattr (fds, TCSANOW, &new_term_settings); 

} 

При чтении из трубы, можно сделать не блокирующем чтения(), которая будет возвращать после того, как, например, 5 секунд. Проблема в том, что если я выполняю команду типа «ls», которая возвращается в течение нескольких мс, она будет ждать полные 5 секунд перед возвратом.

Я понимаю, что с помощью физического терминала GUI, а не для терминала psuedo, пользователь может нажать CTRL^D и отправить EOF в конце каждого вывода.

Я хочу этот эффект, поэтому моя программа может сказать «ОК, я получил этот определенный байт, что означает, что терминал завершен, и теперь я могу вернуть этот вывод обратно вызывающему, и я знаю, что нет больше вывода для чтения ".

Я понимаю, что это делается с помощью функции termios() (или это оболочка stty), но я не могу заставить ее работать. Я хочу, чтобы терминал послал мне '|' char вместо ctrl^d (\ x04) после завершения вывода, но он не работает.

Для ясности, после завершения вывода (через read()), я хочу получить '|' байт. Так что, если я посылаю команду «PWD», я получаю этот выход:

$ pwd 
/home/user/dir 
$| 

Может кто-то пожалуйста, скажите мне, как изменить этот код, чтобы достигнуть того эффекта?

Благодарим за помощь.

EDIT - выберите код()

while ((bytes = select(pipe + 1, &fd_in, NULL, NULL, &tv))) 
{  
      if (FD_ISSET(pipe, &fd_in)) 
      { 

       read (pipe...) 

Поведение выше кода, как я описал, ждать полной стоимости ТВ, даже если нет ничего на трубе, прежде чем вернуться ,

+0

Параметр '.c_cc [VEOF]' специальный символ используется только в режиме "канонической" ('ICANON' бит установлен в' .c_lflags'), но 'cfmakeraw' устанавливает "сырой" режим (' ICANON' бит не задано). –

ответ

1

Значение c_cc[VEOF] не будет отправлено вам. Например, значение по умолчанию c_cc[VEOF] равно CTRL-D, но вы не увидите CTRL-D в конце файла, когда пользователь нажимает CTRL-D. Вместо этого вы будете уведомлены (например, по read(), возвращающему 0), что вы достигнете конца файла.

Обычно, когда ребенок совершает свою работу, он явно укажет close() на рабочую сторону pty, так что основная сторона pty получит EOF.

Относительно

я могу сделать неблокированное чтение(), которая будет возвращать после того, как, например, 5 секунд. Проблема в том, что если я выполню команду типа «ls», которая возвращается в несколько мс, , она будет ждать полные 5 секунд перед возвратом.

Не знаю, как писать код, но вы можете использовать select() или poll(), которые могут предупредить вас сразу, когда есть данные доступная для чтения.


Согласно странице руководства select() «s:

select() и pselect() позволяют программе контролировать несколько дескрипторов файлов, не дожидаясь , пока один или несколько файловых дескрипторов, становятся„готовы“ для некоторых класс операций ввода-вывода (например, вход возможен). Дескриптор файла считается готовым, если возможно выполнить соответствующую операцию ввода-вывода (например, read(2) без блокировки или достаточно мало write(2)).

+0

Это то, чего я боялся. Я использую non blocking read() через select(). Есть ли способ сделать read() return 0 без ожидания значения, определенного в timeval, переданного select() в дескрипторе файла read()? Я хочу избежать ожидания полного значения timeval, прошедшего для выбора, если программа вернется до этого. Спасибо за вашу помощь. – termquestion

+0

Вы можете установить '.c_cc [VTIME]', чтобы установить тайм-аут в deciseconds в режиме «raw» (неканонический). –

+0

Я вижу по другому вопросу, что VTIME не влияет на неблокирующие сокеты. – termquestion

Смежные вопросы