- bookworm 4.18.1-1
ioctl_tty(2) | System Calls Manual | 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
- Вставить заданный байт в очередь ввода.
Перенаправление вывода консоли¶
- 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 }
СМ. ТАКЖЕ¶
ПЕРЕВОД¶
Русский перевод этой страницы руководства был сделан Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.
3 мая 2023 г. | Linux man-pages 6.05.01 |