Выбрать главу

Кроме того, что уже было отмечено, эти функции возвращают 0 в случае успеха и -1 при ошибке. Вызовы функций, которые можно использовать для управления терминалом, описаны ниже.

int tcgetattr(int fd, struct termios * t);

Восстанавливает текущие настройки файлового дескриптора fd и помещает их в структуру, на которую указывает t.

int tcsetattr(int fd, int options, struct termios * t);

Устанавливает текущие настройки терминала для файлового дескриптора fd в настройки, приведенные в t. Всегда используйте tcgetattr() для заполнения t, затем модифицируйте его. Никогда не заполняйте t вручную: некоторые системы требуют установки или снятия флагов, кроме флагов, определенных POSIX, поэтому заполнение вручную является непереносимым.

Аргумент options определяет, когда изменения вступают в силу.

TCSANOW Изменение немедленно вступает в силу.
TCSADRAIN Изменение вступает в силу после того, как передаются все входные данные, уже записанные в fd; перед вступлением в силу оно очищает очередь. Необходимо использовать это при смене выходных параметров.
TCSAFLUSH Изменение вступает в силу после того, как выходная очередь была очищена; входная же очередь отбрасывается перед вступлением изменений в силу.

Если система не может обработать некоторые настройки, например, скорость передачи данных, ей разрешается игнорировать их без выдачи сообщения об ошибке. Единственный способ, с помощью которого можно узнать, были ли приняты настройки — вызвать tcgetattr() и сравнить содержимое возвращаемой им структуры с содержимым структуры, переданной tcsetattr().

Поэтому более переносимые приложения используют код вроде показанного ниже.

#include <termios.h>

struct termios save;

struct termios set;

struct termios new;

int fd;

...

tcgetattr(fd, &save);

set = save;

cfsetospeed(&set, B2400);

cfsetispeed(&set, B2400);

tcsetattr(fd, &set);

tcgetattr(fd, &new);

if ((cfgetospeed(&set) != B2400) ||

 (cfgetispeed(&set) != B2400)) {

 /* объяснение */

}

Обратите внимание, что если не имеет значения, "зависнет" ли настройка termios, лучше проигнорировать это условие, как делается в robin.

speed_t cfgetospeed(struct termios * t);

speed_t cfgetispeed(struct termios * t);

Извлекает скорость, соответственно, вывода или ввода из t. Эти функции возвращают символическую скорость, такую же, которая дается cfsetospeed() и cfsetispeed().

int cfsetospeed(struct termios * t, speed_t speed);

int cfsetispeed(struct termios * t, speed_t speed);

Устанавливает, соответственно, вывода или ввода в t на speed. Обратите внимание, что эта функция не меняет скорость соединения на любом файловом дескрипторе; она просто устанавливает скорость в структуре termios. Скорость, как и другие характеристики, применяется к файловому дескриптору с помощью tcsetattr().

Эти функции принимают символическую скорость — то есть число, соответствующее определению одного из следующих макросов, имена которых определяют скорость в битах в секунду: B0 (0 бит в секунду, определяет отключенное состояние) B50, B75, B110, B134[113], B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000 или B4000000. B57600 и выше в POSIX не описаны; переносимые исходные коды использует их только в том случае, если они защищены операторами #ifdef.

По мере того, как будут разрабатываться драйверы Linux для оборудования, поддерживающего другие скорости передачи данных, в заголовочный файл будут добавляться новые символические скорости.

В настоящий момент скорость ввода игнорируется. Интерфейс termios устанавливает отдельные скорости ввода и вывода для асинхронного оборудования, допускающего раздельные скорости, но такое оборудование встречается довольно редко. Просто вызовите cfsetospeed() и cfsetispeed() попарно, чтобы ваш код продолжил работать в системах, поддерживающих раздельные скорости.

Не все tty поддерживают все скорости — последовательные порты на стандартных ПК не поддерживают более 115 200 бит/с. Как уже упоминалось выше, если для вас имеет значение, вступит ли в силу определенная настройка, необходимо использовать tcgetattr() для проверки после того, как вы попытаетесь установить ее с помощью tcsetattr(). Также обратите внимание, что установленная вами скорость является необязательной. Некоторые tty, например, локальные консоли, благополучно принимают и игнорируют любую установленную вами скорость.

int tcsendbreak(int fd, int duration)

Посылает поток нулей в fd, чтобы узнать определенную длительность (duration), которая также известна как разрыв. Если duration равняется 0, разрыв длится не менее 250 и не более 500 миллисекунд. К сожалению, POSIX не определяет элемент, длительность которого измеряется, поэтому единственной переносимой величиной для duration является 0. В Linux длительность увеличивает разрыв; 0 или 1 задают длительность между четвертью секунды и полсекунды; 2 — между полсекунды и секундой и так далее.

int tcdrain(int fd)

Ожидает, пока не передадутся все входные данные, ожидающие в данный момент на файловом дескрипторе fd.

int tcflush(int fd, int queue_selector)

Отбрасывает некоторые данные в файловом дескрипторе fd в зависимости от величины queue_selector.

TCIFLUSH Сбрасывает на диск все полученные, но еще не прочитанные интерфейсом данные.
TCOFLUSH Сбрасывает на диск все данные, записанные в интерфейс, но еще не отправленные.
TCIOFLUSH Сбрасывает на диск все ожидающие входные и выходные данные.
вернуться

113

B134 в действительности равняется 134,5 бит/с, скорость, используемая устаревшим терминалом IBM.