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