STREAMIO(7) STREAMIO(7)
НАЗВАНИЕ
streamio - управление псевдоустройствами
СИНТАКСИС
#include
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 байт. Требуется включаемый файл . При неудаче переменная 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
присваивается код ошибки.
|