|
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
присваивается код ошибки.
|
|