IOCTL_TTY(2)

ИМЯ
ioctl_tty - вызовы ioctl для терминалов и последовательных портов

ОБЗОР
#include <termios.h>

int ioctl(int fd, int cmd, ...);

ОПИСАНИЕ
Вызов ioctl(2) для терминалов и последовательных портов принимает много разных параметров команд. Большинство из них требуют при этом третий аргумент разных типов, далее по тексту называемый argp или arg.

Вызовы ioctl используются только в непереносимых программах. По возможности старайтесь везде использовать интерфейс POSIX, описанный в termios(3).

  Определение и установка атрибутов терминала

TCGETS	struct termios *argp
    Эквивалентно tcgetattr(fd, argp).
    Получить текущие настройки последовательного порта.

TCSETS	const struct termios *argp
    Эквивалентно tcsetattr(fd, TCSANOW, argp).
    Установить новые текущие настройки последовательного порта.

TCSETSW	const struct termios *argp
    Эквивалентно tcsetattr(fd, TCSADRAIN, argp).
    Позволить очистить буфер вывода и установить новые текущие настройки последовательного порта.

TCSETSF	const struct termios *argp
    Эквивалентно tcsetattr(fd, TCSAFLUSH, argp).
    Позволить очистить буфер вывода, отменить ожидаемые данные на входе и установить новые текущие настройки последовательного порта.

Следующие четыре вызова ioctl аналогичны TCGETS, TCSETS, TCSETSW, TCSETSF, за исключением того, что они работают с struct termio *, а не с struct termios *.

    TCGETA    struct termio *argp

    TCSETA    const struct termio *argp

    TCSETAW    const struct termio *argp

    TCSETAF    const struct termio *argp

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

TIOCGLCKTRMIOS	struct termios *argp
    Получить состояние блокировки структуры termios терминала.

TIOCSLCKTRMIOS	const struct termios *argp
    Установить состояние блокировки структуры termios терминала. Это может делать только процесс с мандатом CAP_SYS_ADMIN.

  Определение и установка размера окна
Размеры окон хранятся в ядре, но не используются им (за исключением случаев виртуальных консолей, где ядро обновляет размер окна при его изменении, например из-за загрузки новых шрифтов).

Следующие константы и структура определены в <sys/ioctl.h>.

TIOCGWINSZ	struct winsize *argp
    Получить размер окна.

TIOCSWINSZ	const struct winsize *argp
    Установить размер окна.

Структура, используемая этими системными вызовами ioctl, определяется так:

    struct winsize {
        unsigned short ws_row;
        unsigned short ws_col;
        unsigned short ws_xpixel;   /* не используется */
        unsigned short ws_ypixel;   /* не используется */
    };

При изменении размера окна отправляется сигнал SIGWINCH группе активных (foreground) процессов.

  Отправка сигнала Break

TCSBRK	int arg
    Эквивалентно tcsendbreak(fd, arg).
    Если терминал использует асинхронную передачу данных и arg равно нулю, то отправляется сигнал break (поток нулевых битов) в течении 0.25 - 0.5 секунд. Если терминал не использует асинхронную передачу данных, то либо сигнал break не отправляется, либо функция просто завершает работу, ничего не исполняя. Если arg не равно нулю, то неизвестно, что произойдет.

    (В SVr4, UnixWare, Solaris, Linux tcsendbreak(fd,arg) ненулевые значение arg воспринимается аналогично вызову tcdrain(fd). В SunOS arg воспринимается как множитель и отправляет поток битов в arg раз дольше, чем для нулевого значения arg. В DG/UX и AIX arg (если оно не равно нулю) воспринимается как временной интервал в миллисекундах. В HP-UX arg игнорируется.)

TCSBRKP	int arg
    Так называемая «POSIX-версия» TCSBRK. Она воспринимает ненулевые значения arg как временной интервал в децисекундах (1/10 секунды), и ничего не делает, если драйвер не поддерживает сигналы break.

TIOCSBRK	void
    Включить сигнал break, то есть начать отправку нулевых битов.

TIOCCBRK	void
    Выключить сигнал break, то есть прекратить отправку нулевых битов.

  Программное управление потоком

TCXONC	int arg
    Эквивалентно tcflow(fd, arg).
    Смотрите tcflow(3) со значениями аргументов TCOOFF, TCOON, TCIOFF, TCION.

  Счетчик буфера и очистка

FIONREAD	int *argp
    Получить количество байтов в буфере ввода.

TIOCINQ	int *argp
    То же что и FIONREAD.

TIOCOUTQ	int *argp
    Получить количество байтов в буфере вывода.

TCFLSH	int arg
    Эквивалентно tcflush(fd, arg).
    Смотрите tcflush(3) со значениями аргументов TCIFLUSH, TCOFLUSH, TCIOFLUSH.

  Мнимый ввод

TIOCSTI	const char *argp
    Вставить заданный байт в очередь ввода.

  Перенаправление вывода консоли

TIOCCONS	void
    Перенаправляет вывод, который должен идти на /dev/console или /dev/tty0, на указанный терминал. Если это был основной псевдо-терминал, то вывод отправляется на подчинённый. В Linux до версии 2.6.10 кто угодно мог делать это, пока вывод не был ещё ни разу перенаправлен; начиная с версии 2.6.10 только процесс с мандатом CAP_SYS_ADMIN может делать это. Если вывод уже был перенаправлен, то будет выдана ошибка EBUSY, но перенаправление можно остановить с помощью этого вызова ioctl с fd, указывающим на /dev/console или /dev/tty0.

  Управляющий терминал

TIOCSCTTY	int arg
    Сделать заданный терминал управляющим для вызывающего процесса. Вызывающий процесс должен быть лидером сеанса и не иметь управляющего терминала. Для этого случая значение arg должно быть равно 0.

    Если этот терминал уже является управляющим для другой группы сеансов, то ioctl завершается с ошибкой EPERM, если только вызывающий не имеет мандата CAP_SYS_ADMIN и arg не равно 1 — в этом случае терминал отбирается и все процессы, где он был управляющим, теряют его.

TIOCNOTTY	void
    Если заданный терминал является управляющим для вызывающего процесса, то выполняется отключение этого управляющего терминала. Если процесс был лидером сеанса, то активной группе процессов посылаются сигналы SIGHUP и SIGCONT, и все процессы в этом сеансе теряют управляющий терминал.

  Группа процессов и идентификатор сеанса

TIOCGPGRP	pid_t *argp
    При успешном выполнении эквивалентно *argp = tcgetpgrp(fd).
    Получить идентификатор активной группы процессов данного терминала.

TIOCSPGRP	const pid_t *argp
    Эквивалентно tcsetpgrp(fd, *argp).
    Установить идентификатор активной группы процессов данного терминала.

TIOCGSID	pid_t *argp
    Получить идентификатор сеанса данного терминала. Завершается ошибкой ENOTTY, если терминал не является основным псевдо-терминалом и не является управляющим для вызывающего процесса. Странно.

  Закрытый (Exclusive) режим

TIOCEXCL	void
    Перевести терминал в закрытый режим. Дальнейшие операции open(2) с терминалом запрещены (выдают ошибку EBUSY, если процесс не имеет мандата CAP_SYS_ADMIN).

TIOCGEXCL	int *argp
    (начиная с Linux 3.8) Если терминал находится в закрытом режиме, поместить ненулевое значение в расположение, указанное argp; в противном случае, поместить ноль в *argp.

TIOCNXCL	void
    Отменить закрытый режим.

  Параметры линии

TIOCGETD	int *argp
    Получить параметры линии для терминала.

TIOCSETD	const int *argp
    Установить параметры линии для терминала.

  Вызовы ioctl для псевдо-терминала

TIOCPKT	const int *argp
    Включить (если *argp не равно нулю) или отключить пакетный режим. Может применяться только к основному псевдо-терминалу (иначе будет возвращено ENOTTY). В пакетном режиме каждый последующий read(2) возвращает пакет, содержащий либо один ненулевой управляющий байт, либо один нулевой байт (' ') с последующими данными, записанными на подчинённом псевдо-терминале. Если первый байт не равен TIOCPKT_DATA (0), то он логически складывается с одним или несколькими следующими битами:

    TIOCPKT_FLUSHREAD   Очередь чтения терминала очищается.
    TIOCPKT_FLUSHWRITE  Очередь записи терминала очищается.
    TIOCPKT_STOP        Вывод на терминал останавливается.
    TIOCPKT_START       Вывод на терминал перезапускается.
    TIOCPKT_DOSTOP      Символами запуска/останова являются ^S/^Q.
    TIOCPKT_NOSTOP      Символами запуска/останова не являются ^S/^Q.

    При использовании этого режима наличие состояния управляющей информации, считываемой с основного псевдо-терминала, может быть определено с помощью select(2) для исключительных условий или poll(2) по событию POLLPRI.

    Этот режим используется rlogin(1) и rlogind(8) для реализации удалённого эха с локально управляемым потоком с помощью ^S/^Q для удалённого входа.

TIOCGPKT	const int *argp
    (начиная с Linux 3.8) Вернуть текущую настройку пакетного режима в виде целого в память, на которую указывает argp.

TIOCSPTLCK	int *argp
    Назначить (если *argp не равно нулю nonzero) или удалить (если *argp равно нулю) устройство подчинённого псевдо-терминала (также смотрите unlockpt(3)).

TIOCGPTLCK	int *argp
    (начиная с Linux 3.8) Поместить текущее состояние блокировки устройства подчинённого псевдо-терминала в расположение, на которое указывает argp.

TIOCGPTPEER	int flags
    (начиная с Linux 4.13) Открыть (флаги flags как у open(2)) переданный в fd файловый дескриптор, который ссылается на основной псевдо-терминал, и вернуть новый файловый дескриптор, который ссылается на ответное устройство подчинённого псевдо-терминала. Данная операция может выполняться независимо от доступности имени подчинённого устройства в пространстве монтирования вызывающего процесса.

    Безопасным приложениям, работающим с пространствами имён, лучше использовать эту операцию вместо open(2) с путём, возвращаемым ptsname(3) и подобных библиотечных функций, имеющих небезопасные программные интерфейсы (например, в некоторых случаях может получиться путаница при использовании ptsname(3) с путём, если файловая система devpts была смонтирована в другое пространство имён).

Вызовы ioctl для BSD — TIOCSTOP, TIOCSTART, TIOCUCNTL, TIOCREMOTE — не реализованы в Linux.

  Управление модемом

TIOCMGET	int *argp
    Получить состояние битов модема.

TIOCMSET	const int *argp
    Установить состояние битов модема.

TIOCMBIC	const int *argp
    Очистить указанные биты модема.

TIOCMBIS	const int *argp
    Установить указанные биты модема.

Приведёнными выше ioctl используются следующие биты:

TIOCM_LE        DSR (источник данных готов/линия включена)
TIOCM_DTR       DTR (сигнал готовности терминала)
TIOCM_RTS       RTS (запрос на передачу)
TIOCM_ST        Вторичный TXD (передача)
TIOCM_SR        Вторичный RXD (приём)
TIOCM_CTS       CTS (разрешение на передачу)
TIOCM_CAR       DCD (обнаружен информационный сигнал)
TIOCM_CD         см. TIOCM_CAR
TIOCM_RNG       RNG (звонок)
TIOCM_RI         см. TIOCM_RNG
TIOCM_DSR       DSR (источник данных готов)

TIOCMIWAIT	int arg
    Ждать изменения любого из 4 битов модема (DCD, RI, DSR, CTS). Интересующие биты указываются в arg в виде битовой маски с помощью операции OR значений TIOCM_RNG, TIOCM_DSR, TIOCM_CD и TIOCM_CTS. Чтобы понять какие биты изменились вызывающий должен использовать TIOCGICOUNT.

TIOCGICOUNT	struct serial_icounter_struct *argp
    Получить счётчики входных прерываний последовательной линии (DCD, RI, DSR, CTS). Счётчики записываются в структуру serial_icounter_struct, на которую указывает argp.

    Замечание: считаются переходы 1->0 и 0->1, за исключением RI, где учитывается только переход 0->1.

  Маркировка линии как локальной

TIOCGSOFTCAR	int *argp
    («получение флага программной несущей») Получить состояние флага CLOCAL в поле c_cflag структуры termios.

TIOCSSOFTCAR	const int *argp
    («установка флага программной несущей») Установить флаг CLOCAL в поле c_cflag структуры termios при *argp не равном нулю или очистить его в противном случае.

Если флаг CLOCAL для линии не установлен, то учитывается сигнал DCD, а вызов open(2) для соответствующего терминала будет блокирован, пока не появится сигнал DCD ( если не установлен флаг O_NONBLOCK). Если флаг CLOCAL установлен, то линия ведёт себя так, как если DCD установлен всегда. Программное задание несущего сигнала обычно включено для локальных устройств и выключено для модемных линий.

  Вызовы, определённые только в Linux
Описание вызова ioctl TIOCLINUX смотрите в ioctl_console(2).

  Отладка ядра
#include <linux/tty.h>

TIOCTTYGSTRUCT	struct tty_struct *argp
    Получить структуру tty_struct, соответствующую fd. Эта команда удалена в Linux 2.5.67.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При нормальном завершении работы системный вызов ioctl(2) возвращает 0. При ошибке возвращается -1 и соответствующим образом устанавливается переменная errno.

ОШИБКИ

EINVAL
    Неизвестный параметр команды.

ENOIOCTLCMD
    Неизвестная команда.

ENOTTY
    Неподходящий fd.

EPERM
    Недостаточно прав.

ПРИМЕР
Проверка состояния DTR на последовательном порту.

    #include <termios.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    int
    main(void)
    {
        int fd, serial;
        fd = open("/dev/ttyS0", O_RDONLY);
        ioctl(fd, TIOCMGET, &serial);
        if (serial & TIOCM_DTR)
            puts("TIOCM_DTR установлен");
        else
            puts("TIOCM_DTR не установлен");
        close(fd);
    }

СМОТРИТЕ ТАКЖЕ
ldattach(1), ioctl(2), ioctl_console(2), termios(3), pty(7)