Scroll to navigation

ioctl(2) System Calls Manual ioctl(2)

ИМЯ

ioctl - управляет устройством

LIBRARY

Standard C library (libc, -lc)

СИНТАКСИС

#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);

ОПИСАНИЕ

Системный вызов ioctl() изменяет параметры нижележащего устройства специальных файлов. В частности, через запросы ioctl() можно управлять многими оперативными характеристиками специальных символьных файлов (например, терминалов). В качестве аргумента fd должен быть указан открытый файловый дескриптор.

Второй аргумент является кодом запроса, значение которого зависит от устройства. Третий аргумент является нетипизированным указателем на память. Обычно, это char *argp (было до тех пор, пока в C не появился vvoid *) и далее он будет называться именно так.

An ioctl() request has encoded in it whether the argument is an in parameter or out parameter, and the size of the argument argp in bytes. Macros and defines used in specifying an ioctl() request are located in the file <sys/ioctl.h>. See NOTES.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Usually, on success zero is returned. A few ioctl() requests use the return value as an output parameter and return a nonnegative value on success. On error, -1 is returned, and errno is set to indicate the error.

ОШИБКИ

Значение fd не является правильным файловым дескриптором.
argp ссылается на недоступную область памяти.
Неправильное значение request или argp.
Значение fd не связано со специальным символьным устройством.
Указанный запрос не применяется к типу объекта, на который ссылается файловый дескриптор fd.

СТАНДАРТЫ

Нет единого стандарта. Аргументы, возвращаемые значения и семантика ioctl() варьируются в соответствии с драйвером устройства (вызов, используемый как всеохватывающий, не полностью соответствует потоковой модели ввода/вывода в UNIX).

The ioctl() system call appeared in Version 7 AT&T UNIX.

ЗАМЕЧАНИЯ

Чтобы использовать этот вызов требуется открытый файловый дескриптор. Часто вызов open(2) приводит к нежелательным эффектам, которых в Linux можно избежать указав флаг O_NONBLOCK.

Структура ioctl

Значения команд ioctl являются 32-битными константами. В принципе, эти константы являются полностью случайными, но некоторые люди пытаются увидеть в них определённую закономерность.

В старом Linux, в основном, были 16-битные константы, в которых последний байт является серийным номером, а предшествующим байт(ами) указывался драйвер. Иногда использовался старший номер устройства: 0x03 для ioctl вызовов HDIO_*, 0x06 для ioctl вызовов LP*. Иногда использовались одна или несколько букв ASCII. Например, TCGETS имеет значение 0x00005401, с буквой 0x54 = 'T', указывающей на драйвер терминала и CYGETTIMEOUT имеет значение 0x00435906, с буквами 0x43 0x59 = 'C' 'Y', указывающими на драйвер cyclades.

Позже (0.98p5) в номер была встроена дополнительная информация. Появилось 2 бита направления (00: нет, 01: запись, 10: чтение, 11: чтение/запись), за которыми следовали 14 бит размера (указывают размер аргумента), за которыми следовали 8 бит типа (собирающих вызовы ioctl в группы по назначению или общему драйверу) и, наконец, 8 бит серийного номера.

Макросы, описывающие эту структуру, расположены в <asm/ioctl.h>, _IO(type,nr) и {_IOR,_IOW,_IOWR}(type,nr,size). Они используют sizeof(size), так что говорить о размере здесь является неправильным — это третий параметр типа данных.

Заметим, что биты размера очень ненадёжны: во многих случаях они ошибочны или потому что ошибочный макрос использует sizeof(sizeof(struct)) или потому что таковы унаследованные значение.

Таким образом, мы видим, что новая структура имеет только недостатки: она не помогает в проверке, и приводит к различным значениям у разных архитектур.

СМ. ТАКЖЕ

execve(2), fcntl(2), ioctl_console(2), ioctl_fat(2), ioctl_ficlone(2), ioctl_ficlonerange(2), ioctl_fideduperange(2), ioctl_fslabel(2), ioctl_getfsmap(2), ioctl_iflags(2), ioctl_ns(2), ioctl_tty(2), ioctl_userfaultfd(2), open(2), sd(4), tty(4)

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан 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.

30 октября 2022 г. Linux man-pages 6.02