ioctl_tty(2)

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

LIBRARY
Standard C library (libc, -lc)

СИНТАКСИС
#include <sys/ioctl.h>
#include <asm/termbits.h>   /* Definition of struct termios,
                               struct termios2, and
                               Bnnn, BOTHER, CBAUD, CLOCAL,
                               TC*{FLUSH,ON,OFF} and other constants */

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

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

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

Please note that struct termios from <asm/termbits.h> is different and incompatible with struct termios from <termios.h>. These ioctl calls require struct termios from <asm/termbits.h>.

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

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).

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

The following four ioctls, added in Linux 2.6.20, are just like TCGETS, TCSETS, TCSETSW, TCSETSF, except that they take a struct termios2 * instead of a struct termios *. If the structure member c_cflag contains the flag BOTHER, then the baud rate is stored in the structure members c_ispeed and c_ospeed as integer values. These ioctls are not supported on all architectures.
    TCGETS2 | struct termios2 *argp
    TCSETS2 | const struct termios2 *argp
    TCSETSW2 | const struct termios2 *argp
    TCSETSF2 | const struct termios2 *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.

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

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.

TIOCSERGETLSR
    Аргумент: int *argp

    Get line status register. Status register has TIOCSER_TEMT bit set when output buffer is empty and also hardware transmitter is physically empty.

    Does not have to be supported by all serial tty drivers.

    tcdrain(3) does not wait and returns immediately when TIOCSER_TEMT bit is set.

  Мнимый ввод

TIOCSTI
    Аргумент: const char *argp

    Вставить заданный байт в очередь ввода.

    Since Linux 6.2, this operation may require the CAP_SYS_ADMIN capability (if the dev.tty.legacy_tiocsti sysctl variable is set to false).

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

TIOCCONS
    Аргумент: void

    Redirect output that would have gone to /dev/console or /dev/tty0 to the given terminal. If that was a pseudoterminal master, send it to the slave. Before Linux 2.6.10, anybody can do this as long as the output was not redirected yet; since Linux 2.6.10, only a process with the CAP_SYS_ADMIN capability may do this. If output was redirected already, then EBUSY is returned, but redirection can be stopped by using this ioctl with fd pointing at /dev/console or /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

    При успешном выполнении эквивалентно *argp = tcgetsid(fd).

    Получить идентификатор сеанса данного терминала. Завершается ошибкой 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

    Enable (when *argp is nonzero) or disable packet mode. Can be applied to the master side of a pseudoterminal only (and will return ENOTTY otherwise). In packet mode, each subsequent read(2) will return a packet that either contains a single nonzero control byte, or has a single byte containing zero ('\0') followed by data written on the slave side of the pseudoterminal. If the first byte is not TIOCPKT_DATA (0), it is an OR of one or more of the following bits:

    TIOCPKT_FLUSHREAD | The read queue for the terminal is flushed.
    TIOCPKT_FLUSHWRITE | The write queue for the terminal is flushed.
    TIOCPKT_STOP | Output to the terminal is stopped.
    TIOCPKT_START | Output to the terminal is restarted.
    TIOCPKT_DOSTOP | The start and stop characters are ^S/^Q.
    TIOCPKT_NOSTOP | The start and stop characters are not ^S/^Q.

    While packet mode is in use, the presence of control status information to be read from the master side may be detected by a select(2) for exceptional conditions or a poll(2) for the POLLPRI event.

    This mode is used by rlogin(1) and rlogind(8) to implement a remote-echoed, locally ^S/^Q flow-controlled remote login.

TIOCGPKT
    Аргумент: const int *argp

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

TIOCSPTLCK
    Аргумент: int *argp

    Set (if *argp is nonzero) or remove (if *argp is zero) the lock on the pseudoterminal slave device. (See also 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 (data set ready/line enable)
TIOCM_DTR | DTR (data terminal ready)
TIOCM_RTS | RTS (request to send)
TIOCM_ST | Secondary TXD (transmit)
TIOCM_SR | Secondary RXD (receive)
TIOCM_CTS | CTS (clear to send)
TIOCM_CAR | DCD (data carrier detect)
TIOCM_CD | смотрите TIOCM_CAR
TIOCM_RNG | RNG (ring)
TIOCM_RI | смотрите TIOCM_RNG
TIOCM_DSR | DSR (data set ready)

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.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
The ioctl(2) system call returns 0 on success. On error, it returns -1 and sets errno to indicate the error.

ОШИБКИ

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

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

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

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

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

    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/ioctl.h>
    #include <unistd.h>

    int
    main(void)
    {
        int fd, serial;

        fd = open("/dev/ttyS0", O_RDONLY);
        ioctl(fd, TIOCMGET, &serial);
        if (serial & TIOCM_DTR)
            puts("TIOCM_DTR is set");
        else
            puts("TIOCM_DTR is not set");
        close(fd);
    }

Get or set arbitrary baudrate on the serial port.

    /* SPDX-License-Identifier: GPL-2.0-or-later */

    #include <asm/termbits.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/ioctl.h>
    #include <unistd.h>

    int
    main(int argc, char *argv[])
    {
    #if !defined BOTHER
        fprintf(stderr, "BOTHER is unsupported\n");
        /* Program may fallback to TCGETS/TCSETS with Bnnn constants */
        exit(EXIT_FAILURE);
    #else
        /* Declare tio structure, its type depends on supported ioctl */
    # if defined TCGETS2
        struct termios2 tio;
    # else
        struct termios tio;
    # endif
        int fd, rc;

        if (argc != 2 && argc != 3 && argc != 4) {
            fprintf(stderr, "Usage: %s device [output [input] ]\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        fd = open(argv[1], O_RDWR | O_NONBLOCK | O_NOCTTY);
        if (fd < 0) {
            perror("open");
            exit(EXIT_FAILURE);
        }

        /* Get the current serial port settings via supported ioctl */
    # if defined TCGETS2
        rc = ioctl(fd, TCGETS2, &tio);
    # else
        rc = ioctl(fd, TCGETS, &tio);
    # endif
        if (rc) {
            perror("TCGETS");
            close(fd);
            exit(EXIT_FAILURE);
        }

        /* Change baud rate when more arguments were provided */
        if (argc == 3 || argc == 4) {
            /* Clear the current output baud rate and fill a new value */
            tio.c_cflag &= ~CBAUD;
            tio.c_cflag |= BOTHER;
            tio.c_ospeed = atoi(argv[2]);

            /* Clear the current input baud rate and fill a new value */
            tio.c_cflag &= ~(CBAUD << IBSHIFT);
            tio.c_cflag |= BOTHER << IBSHIFT;
            /* When 4th argument is not provided reuse output baud rate */
            tio.c_ispeed = (argc == 4) ? atoi(argv[3]) : atoi(argv[2]);

            /* Set new serial port settings via supported ioctl */
    # if defined TCSETS2
            rc = ioctl(fd, TCSETS2, &tio);
    # else
            rc = ioctl(fd, TCSETS, &tio);
    # endif
            if (rc) {
                perror("TCSETS");
                close(fd);
                exit(EXIT_FAILURE);
            }

            /* And get new values which were really configured */
    # if defined TCGETS2
            rc = ioctl(fd, TCGETS2, &tio);
    # else
            rc = ioctl(fd, TCGETS, &tio);
    # endif
            if (rc) {
                perror("TCGETS");
                close(fd);
                exit(EXIT_FAILURE);
            }
        }

        close(fd);

        printf("output baud rate: %u\n", tio.c_ospeed);
        printf("input baud rate: %u\n", tio.c_ispeed);

        exit(EXIT_SUCCESS);
    #endif
    }

СМ. ТАКЖЕ
ldattach(8), ioctl(2), ioctl_console(2), termios(3), pty(7)

ПЕРЕВОД
Русский перевод этой страницы руководства был сделан Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 (https://www.gnu.org/licenses/gpl-3.0.html) или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.