STREAMIO(7)

НАЗВАНИЕ
streamio - управление псевдоустройствами

СИНТАКСИС


#include <stropts.h>



int ioctl (fildes, command, arg)

int fildes, command;

ОПИСАНИЕ
Управление псевдоустройствами [см. intro(2)]

выполняется с помощью системного вызова ioctl(2), осуществляющего операции над потоками. Аргументы command и arg передаются в поток, определяемый дескриптором файла fildes и интерпретируются его истоком. Некоторые комбинации аргументов передаются далее модулям или драйверам потока.

Аргумент fildes - это дескриптор открытого файла, определяющий поток. Аргумент command задает выполняемую команду, как описано ниже. Аргумент arg задает дополнительные аргументы для этой команды. Тип аргумента arg зависит от команды. Обычно это int или указатель на какую-либо структуру.

Поскольку управление псевдоустройствами осуществляется с помощью системного вызова ioctl(2), ошибки, описанные в ioctl(2), относятся и к управлению псевдоустройствами. В дополнение к этим ошибкам системный вызов может закончиться неудачей, а переменная errno получит значение EINVAL, если поток, определяемый дескриптором файла, мультиплексируется, либо аргумент command имеет значение, не применимое к этому потоку.

Ошибки могут обнаруживаться модулями и драйверами псевдоустройств. В этом случае модуль или драйвер посылает сообщение, содержащее код ошибки, истоку потока, переменной errno присваивается значение, равное посланному коду ошибки, а соответствующий системный вызов завершается неудачей.

Следующие команды системного вызова ioctl(2) применимы ко всем псевдоустройствам.

I_PUSH
Помещает модуль, на имя которого указывает аргумент arg, на вершину потока, определяемого аргументом fildes, сразу под истоком. Затем вызывается процедура открытия помещенного модуля. При неудаче переменная errno принимает одно из следующих значений:
[EINVAL]
Некорректное имя модуля.
[EFAULT]
Аргумент arg указывает за пределы отведенного процессу адресного пространства.
[ENXIO]
Ошибка в процедуре открытия помещенного модуля.
[ENXIO]
В потоке произошло освобождение линии.
I_POP
Удаляет модуль, расположенный сразу под истоком потока, определяемого аргументом fildes. Аргумент arg должен равняться 0. При неудаче переменная errno принимает одно из следующих значений:
[EINVAL]
В потоке нет ни одного модуля.
[ENXIO]
В потоке произошло освобождение линии.
I_LOOK
Извлекает имя модуля, расположенного сразу под истоком потока, определяемого аргументом fildes, и помещает его (как цепочку символов, завершающуюся нулевым байтом) в буфер, на который указывает аргумент arg. Этот буфер должен иметь длину не менее FMNAMESZ + 1 байт. Требуется включаемый файл <sys/ conf.h>. При неудаче переменная errno принимает одно из следующих значений:
[EFAULT]
Аргумент arg указывает за пределы отведенного процессу адресного пространства.
[EINVAL]
В потоке нет ни одного модуля.
I_FLUSH
Очищает входные или выходные очереди, в зависимости от значения аргумента arg. Допустимыми являются следующие значения:
FLUSHR
Очистить входные очереди.
FLUSHW
Очистить выходные очереди.
FLUSHRW
Очистить входные и выходные очереди.
При неудаче переменная errno принимает одно из следующих значений:
[EINVAL]
Аргумент arg некорректен.
[EAGAIN]
Не удалось захватить буфера для очистки очередей.
[ENXIO]
В потоке произошло освобождение линии.
I_SETSIG
Информирует исток потока о том, что пользователь хочет, чтобы ядро послало ему сигнал SIGPOLL [см. signal(2) и sigset(2)]
, когда в потоке, определяемом аргументом fildes, произойдет определенное событие. Таким образом обеспечивается возможность асинхронной работы с псевдоустройствами. Значение аргумента arg является битной маской, задающей события, при наступлении которых пользователю должен быть послан сигнал. Маска представляет собой логическое ИЛИ следующих констант:
S_INPUT
В очереди на чтение истока, которая была до этого пустой, появилось неприоритетное сообщение. Сообщения нулевой длины при этом тоже обрабатываются.
S_HIPRI
В очереди на чтение истока появилось приоритетное сообщение. Сообщения нулевой длины при этом тоже обрабатываются.
S_OUTPUT
В очереди на запись истока, которая была до этого заполненной, появилось свободное место. Пользователь уведомляется о возможность посылать данные в поток.
S_MSG
Следующим в очереди на чтение истока стало сообщение, содержащее сигнал SIGPOLL.
Пользовать может получать сигналы только при поступлении приоритетных сообщений, если он укажет в качестве маски значение S_HIPRI.

Процессы, желающие получать сигнал SIGPOLL, должны обязательно выдать команду I_SETSIG. Если несколько процессов запросило сигнализацию об одних и тех же событиях одного и того же потока, при наступлении события сигналы будут посланы всем.

Если значение arg равно 0, процесс удаляется из списка процессов, которым нужно посылать сигнал SIGPOLL.

При неудаче переменная errno принимает одно из следующих значений:

[EINVAL]
Аргумент arg некорректен или аргумент arg равен 0, но процесс до этого не просил посылать ему сигнал SIGPOLL.
[EAGAIN]
Не удалось захватить буфера для обработки запроса.
I_GETSIG
Возвращает событие, которое произошло в потоке и по поводу которого процессу был послан сигнал SIGPOLL. События записываются в виде битной маски по адресу, на который указывает аргумент arg. Значения бит те же, что и в команде I_SETSIG [см. выше].

При неудаче переменная errno принимает одно из следующих значений:

[EINVAL]
Процесс не просил посылать ему сигнал SIGPOLL.
[EFAULT]
Аргумент arg указывает за пределы отведенного процессу адресного пространства.
I_FIND
Сравнивает имена модулей, находящихся в потоке, с именем, на которое указывает аргумент arg. Если модуль с таким именем присутствует в потоке, то возвращается 1, если отсутствует - возвращается 0.

При неудаче переменная errno принимает одно из следующих значений:

[EFAULT]
Аргумент arg указывает за пределы отведенного процессу адресного пространства.
[EINVAL]
Имя модуля, на которое указывает arg, некорректно.
I_PEEK
Дает возможность пользователю получить информацию о первом сообщении в очереди на чтение истока потока без удаления самого сообщения из очереди. Аргумент arg указывает на структуру типа struct strpeek:

   struct strpeek {

     struct strbuf ctlbuf;

     struct strbuf databuf;

     long          flags;

   };

Поля ctlbuf.maxlen и databuf.maxlen [см. getmsg(2)] должны быть установлены равными количеству извлекаемых байт из управляющей области и области данных соответственно. Если поле flags имеет значение RS_HIPRI, из очереди на чтение истока будут извлекаться только приоритетные сообщения.

Команда I_PEEK возвращает значение 1, если сообщение было извлечено. Результат равен 0, если в очереди не чтение истока нет сообщений или если установлен флаг RS_HIPRI, а в очереди на чтение истока нет приоритетных сообщений. Ожидание сообщений не производится. При возврате поле ctlbuf задает информацию из управляющей области, databuf - из области данных, flags содержит значение 0 или RS_HIPRI.

При неудаче переменная errno принимает следующее значение:

[EFAULT]
Аргумент arg или компоненты структур ctlbuf или databuf указывают за пределы отведенного процессу адресного пространства.
I_SRDOPT
Устанавливает режим чтения в соответствии со значением аргумента arg. Допустимыми являются следующие значения:
RNORM
Байтный режим, по умолчанию.
RMSGD
Режим сообщений со сбросом.
RMSGN
Режим сообщений без сброса.
Режимы чтения описаны в read(2).

При неудаче переменная errno принимает следующее значение:

[EINVAL]
Аргумент arg некорректен.
I_GRDOPT
Возвращает текущее значение режима чтения, записывая его в целую переменную, на которую указывает аргумент arg. Режимы чтения описаны в read(2).

При неудаче переменная errno принимает следующее значение:

[EFAULT]
Аргумент arg указывает за пределы отведенного процессу адресного пространства.
I_NREAD
Вычисляет количество байт данных в первом сообщении из очереди на чтение истока и присваивает вычисленное значение переменной, на которую указывает аргумент arg. Сам системный вызов возвращает значение, равное количеству сообщений в очереди на чтение истока. Например, если переменной *arg присвоено значение 0, а ioctl возвратил значение, большее 0, значит, следующее сообщение в очереди имеет нулевую длину.

При неудаче переменная errno принимает следующее значение:

[EFAULT]
Аргумент arg указывает за пределы отведенного процессу адресного пространства.
I_FDINSERT
Порождает сообщение, указанное пользователем, добавляет в него информацию о другом потоке и посылает сообщение вниз. Сообщение содержит управляющую область и может содержать область данных. Пользователь передает команде содержимое управляющей области и области данных в разных буферах, как описано ниже.

Аргумент arg указывает на структуру типа struct strfdinsert:


   struct strfdinsert {

     struct strbuf ctlbuf;

     struct strbuf databuf;

     long          flags;

     int           fildes;

     int           offset;

   };

Поле ctlbuf.len [см. putmsg(2)] должно иметь значение, равное размеру указателя плюс количество байт в управляющей области сообщения. Поле fildes задает дескриптор файла другого потока. Поле offset, которое должно быть выравнено по границе слова, задает смещение от начала управляющей области ячейки памяти, куда команда I_FDINSERT занесет указатель на структуру очереди чтения драйвера потока, определяемого fildes. Поле databuf.len должно иметь значение, равное количеству байт в области данных сообщения, или значение 0, если область данных отсутствует.

Поле flags задает тип посылаемого сообщения. Если поле flags имеет значение 0, посылается неприоритетное сообщение, а если поле flags имеет значение RS_HIPRI, посылается приоритетное сообщение. Для неприоритетных сообщений, в случае если очередь на запись потока заполнена, команда I_FDINSERT заблокируется в ожидании свободного места. Для приоритетных сообщений блокировки в этом случае не происходит. Если для потока установлен флаг O_NDELAY, то для неприоритетных сообщений, в случае если очередь на запись потока заполнена, команда I_FDINSERT не блокируется, а завершается неудачей с присваиванием переменной errno значения EAGAIN.

Команда I_FDINSERT посылает сообщения только целиком, и может, вне зависимости от приоритетности сообщения и установки флага O_NDELAY, заблокироваться в ожидании свободных блоков для сообщения в потоке (если при этом не происходит исчерпания системных ресурсов).

При неудаче переменная errno принимает одно из следующих значений:

[EAGAIN]
Указано неприоритетное сообщение, в потоке установлен флаг O_NDELAY и очередь потока на запись заполнена.
[EAGAIN]
Не удалось захватить буфера для посылки сообщения.
[EFAULT]
Аргумент arg или компоненты структур ctlbuf или databuf указывают за пределы отведенного процессу адресного пространства.
[EINVAL]
Или поле fildes не является корректным дескриптором открытого файла, или значение поля offset превосходит значение ctlptr.len, или поле offset не выравнено по границе слова, или значение поля flags некорректно.
[ENXIO]
В потоке произошло освобождение линии.
[ERANGE]
Значение поля databuf.len выходит за пределы минимального или максимального размера сообщения, которые определяются самым верхним модулем потока, или превосходит максимум, заданный при генерации системы, или значение в поле ctlbuf.len превосходит максимум, заданный при генерации системы.
I_STR
Порождает внутреннее управляющее сообщение из данных, указанных пользователем, и посылает сообщение вниз.

Описываемая команда предназначена для посылки управляющих сообщений для определенных модулей или драйверов потока. Информация передается вниз по потоку до тех пор, пока не встретится модуль, который ее обработает и пошлет ответное сообщение вверх. Команда I_STR блокируется до тех пор, пока не придет сообщение, подтверждающее выполнение запрошенного действия или отвергающее его, либо истечет определенный период времени. В случае истечения времени команда завершается неудачей с присваиванием переменной errno значения ETIME.

Только одна команда I_STR может быть активной в потоке, все последующие команды I_STR блокируются до тех пор, пока ответ от активной команды I_STR не дойдет до истока. Время ожидания по умолчанию равен 15 секундам. Наличие флага O_NDELAY [см. open(2)] в этой команде игнорируется.

Аргумент arg должен указывать на структуру типа struct strioctl:


   struct strioctl {

     int  ic_cmd;    /* Команда */

     int  ic_timout; /* Время ожидания */

     int  ic_len;    /* Длина данных */

     char *ic_dp;    /* Указатель на данные */

   };

В поле ic_cmd задается внутренняя команда, предназначенная модулю или драйверу потока. В поле ic_timeout задается время ожидания: -1 - бесконечное, 0 - по умолчанию, > 0 - указанное количество секунд. В поле ic_len задается длина передаваемых данных, а в поле ic_dp - указатель на данные. Поле ic_len используется для двух целей: на входе в нем задается длина передаваемых данных, а на выходе в него записывается длина ответа. Буфер, на который указывает поле ic_dp, должен иметь достаточный размер для приема любого ответа от любого модуля или драйвера потока.

Исток преобразует информацию из структуры strioctl в формат внутреннего управляющего сообщения и посылает это сообщение вниз.

При неудаче переменная errno принимает одно из следующих значений:

[EAGAIN]
Не удалось захватить буфера для посылки сообщения.
[EFAULT]
Аргумент arg или поля ic_dp или ic_len указывают за пределы отведенного процессу адресного пространства.
[EINVAL]
Значение ic_len меньше 0 или больше максимума, заданного при генерации системы, или значение ic_timeout меньше -1.
[ENXIO]
В потоке произошло освобождение линии.
[ETIME]
Период ожидания истек до получения ответа.
Команда I_STR завершается неудачей без ожидания ответа, если истоком получено сообщение об ошибке или освобождении линии. Кроме того, в положительном или отрицательном ответе на сообщение может также содержаться код ошибки. В этом случае I_STR завершается неудачей, а значение переменной errno устанавливается равным полученному коду ошибки.
I_SENDFD
Запрашивает посылку сообщения, содержащего описатель некоторого файла, в исток потока, находящегося на другом конце конвейера, в который входит поток, определяемый аргументом fildes. Файл, об описателе которого идет речь, задается аргументом arg, который должен быть целым числом - дескриптором открытого файла.

Команда I_SENDFD извлекает системный описатель файла с дескриптором arg. Порождается сообщение, в которое записывается этот описатель, а также идентификатор пользователя и идентификатор группы процесса, выполняющего команду I_SENDFD. Сообщение помещается непосредственно в очередь на чтение [см. intro(2)] истока потока на другом конце конвейера, в который входит данный поток.

При неудаче переменная errno принимает одно из следующих значений:

[EAGAIN]
Не удалось захватить буфера для посылки сообщения.
[EAGAIN]
Очередь на чтение истока заполнена и не может принять сообщение, сгенерированное по команде I_SENDFD.
[EBADF]
Аргумент arg не является корректным дескриптором открытого файла.
[EINVAL]
Поток, определяемый аргументом fildes, не входит в конвейер.
[ENXIO]
В потоке произошло освобождение линии.
I_RECVFD
Получает дескриптор файла по сообщению, посланному командой I_SENDFD с другого конца конвейера. Аргумент arg указывает на структуру типа struct strrecvfd:

   struct strrecvfd {

     int            fd;

     unsigned short uid;

     unsigned short gid;

     char           fill [8];

   };

В поле fd возвращается дескриптор файла. В поля uid и gid - идентификатор пользователя и идентификатор группы процесса, выполнявшего команду I_SENDFD.

Если отсутствует флаг O_NDELAY [см. open(2)], команда I_RECVFD блокируется до тех пор, пока не придет какое-нибудь сообщение. Если флаг O_NDELAY присутствует, а в истоке нет никаких сообщений, команда I_RECVFD завершается неудачей с присваиванием переменной errno значения EAGAIN.

Если полученное сообщение действительно послано командой I_SENDFD, образуется новый дескриптор файла, описатель которого передан в сообщении. Новый дескриптор помещается в поле fd структуры типа strrecvfd, на которую указывает аргумент arg.

При неудаче переменная errno принимает одно из следующих значений:

[EAGAIN]
В потоке установлен флаг O_NDELAY и очередь потока на чтение пуста.
[EBADMSG]
Полученное сообщение послано не командой I_SENDFD.
[EFAULT]
Аргумент arg указывает за пределы отведенного процессу адресного пространства.
[EMFILE]
Уже имеется NOFILES дескрипторов открытых файлов.
[ENXIO]
В потоке произошло освобождение линии.
Следующие две команды используются для работы с мультиплексируемыми конфигурациями псевдоустройств:
I_LINK
Соединить два потока, где fildes - это дескриптор файла для потока с мультиплексирующим драйвером, а arg - дескриптор файла для потока с другим драйвером. Поток, заданный аргументом arg, присоединяется к мультиплексирующему драйверу. Команда I_LINK приводит к посылке мультиплексирующим драйвером в исток сообщения, говорящего о завершении операции присоединения. Системный вызов при успехе возвращает идентификатор мультиплексора (который впоследствии используется для отсоединения, см. I_UNLINK). При неудаче возвращается -1.

При неудаче переменная errno принимает одно из следующих значений:

[ENXIO]
В потоке произошло освобождение линии.
[ETIME]
Период ожидания истек до получения ответа.
[EAGAIN]
Не удалось захватить буфера для выполнения запроса.
[EBADF]
Аргумент arg не является корректным дескриптором открытого файла.
[EINVAL]
Поток fildes не поддерживает мультиплексирования.
[EINVAL]
Аргумент arg некорректен или поток arg уже мультиплексируется.
[EINVAL]
Обнаружен "цикл" в мультиплексируемой конфигурации, например, данный исток задан в нескольких местах конфигурации.
Команда I_LINK завершается неудачей без ожидания ответа, если истоком потока fildes получено сообщение об ошибке или освобождении линии. Кроме того, в положительном или отрицательном ответе на сообщение может также содержаться код ошибки. В этом случае команда I_LINK завершается неудачей, а значение переменной errno устанавливается равным полученному коду ошибки.
I_UNLINK
Раз единить два потока, заданные аргументами fildes и arg. Аргумент fildes - это дескриптор файла для потока с мультиплексирующим драйвером, а arg - идентификатор мультиплексора, который был возвращен командой I_LINK при соединении потоков. Если arg равен -1, от потока fildes отсоединяются все присоединенные потоки. Так же как и команда I_LINK, команда I_UNLINK приводит к посылке мультиплексирующим драйвером в исток сообщения, говорящего о завершении операции отсоединения.

При неудаче переменная errno принимает одно из следующих значений:

[ENXIO]
В потоке произошло освобождение линии.
[ETIME]
Период ожидания истек до получения ответа.
[EAGAIN]
Не удалось захватить буфера для посылки ответа.
[EINVAL]
Аргумент arg некорректен.
Команда I_UNLINK завершается неудачей без ожидания ответа, если истоком потока fildes получено сообщение об ошибке или освобождении линии. Кроме того, в положительном или отрицательном ответе на сообщение может также содержаться код ошибки. В этом случае команда I_UNLINK завершается неудачей, а значение переменной errno устанавливается равным полученному коду ошибки.

СМ. ТАКЖЕ
intro(2), close(2), fcntl(2), getmsg(2), ioctl(2), open(2), poll(2), putmsg(2), read(2), signal(2), sigset(2), write(2) в Справочнике программиста.

ДИАГНОСТИКА
Если не оговорено противное, то в случае успеха результат, возвращаемый системным вызовом ioctl, равен 0. В случае неудачи возвращается -1, а переменной errno присваивается код ошибки.