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.

ОШИБКИ

EBADF
    Значение fd не является правильным файловым дескриптором.

EFAULT
    argp ссылается на недоступную область памяти.

EINVAL
    Неправильное значение request или argp.

ENOTTY
    Значение fd не связано со специальным символьным устройством.

ENOTTY
    Указанный запрос не применяется к типу объекта, на который ссылается файловый дескриптор fd.

ВЕРСИИ
Arguments, returns, and semantics of ioctl() vary according to the device driver in question (the call is used as a catch-all for operations that don't cleanly fit the UNIX stream I/O model).

СТАНДАРТЫ
None.

ИСТОРИЯ
Version 7 AT&T UNIX.

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

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

The old Linux situation was that of mostly 16-bit constants, where the last byte is a serial number, and the preceding byte(s) give a type indicating the driver. Sometimes the major number was used: 0x03 for the HDIO_* ioctls, 0x06 for the LP* ioctls. And sometimes one or more ASCII letters were used. For example, TCGETS has value 0x00005401, with 0x54 = 'T' indicating the terminal driver, and CYGETTIMEOUT has value 0x00435906, with 0x43 0x59 = 'C' 'Y' indicating the cyclades driver.

Позже (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 (https://www.gnu.org/licenses/gpl-3.0.html) или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

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