ИМЯ
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.
Перенаправление
  вывода
  консоли
  - 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
- Отменить
      закрытый
      режим.
Вызовы 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).
ВОЗВРАЩАЕМОЕ
  ЗНАЧЕНИЕ
При
    нормальном
    завершении
    работы
    системный
    вызов ioctl(2)
    возвращает
    0. При ошибке
    возвращается
    -1 и
    соответствующим
    образом
    устанавливается
    переменная
    errno.
ПРИМЕР
Проверка
    состояния 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);
}