Установить связь между путём и администратором ресурса
#include <sys/iofunc.h>#include <sys/dispatch.h>int resmgr_attach ( dispatch_t *dpp,resmgr_attr_t *attr,const char *path,enum _file_type file_type,unsigned flags,const resmgr_connect_funcs_t *connect_funcs,const resmgr_io_funcs_t *io_funcs,RESMGR_HANDLE_T *handle );
NULL
, или путь, который требуется зарегистрировать в менеджере ресурсов.<sys/ftype.h>
): libc
Функция resmgr_attach() помещает path в пространство имен и связывает запросы по этому пути со структурой диспетчера dpp.
Большинство из перечисленных выше типов файлов используются для специальных служб, с которыми связана их собственная функция открытия. Например, менеджер mqueue указывает file_type как _FTYPE_MQUEUE
, а mq_open() запрашивает совпадение пути того же типа.
Следует указать _FTYPE_ANY
для обычных файловых систем и простых устройств, таких как последовательные порты, которые не имеют своего собственного типа открытия, или если менеджер ресурсов может обрабатывать тип службы или действовать как узел перенаправления для диспетчера, который имеет тип открытия. Большинство менеджеров ресурсов относятся к этому типу.
Пользовательский менеджер ресурсов не будет получать сообщения об открытии неподходящего типа. В следующей таблице показаны различные типы открытых функций и типы путей, которым они будут соответствовать.
Функция: | file_type: | Соответствует пути для типа: |
---|---|---|
mq_open() | _FTYPE_MQUEUE | _FTYPE_ANY или _FTYPE_MQUEUE |
open() | _FTYPE_ANY | Все типы |
pipe() | _FTYPE_PIPE | _FTYPE_ANY или _FTYPE_PIPE |
sem_open() | _FTYPE_SEM | _FTYPE_ANY или _FTYPE_SEM |
shm_open() | _FTYPE_SHMEM | _FTYPE_ANY или _FTYPE_SHMEM |
socket() | _FTYPE_SOCKET | _FTYPE_ANY или _FTYPE_SOCKET |
Универсальный вызов open() можно использовать для открытия пути любого типа.
Если требуется использовать функции POSIX, то существует возможность вызвать iofunc_func_init(), чтобы заполнить таблицы функций подключения и ввода/вывода функциями-обработчиками по умолчанию, предоставляемыми библиотекой слоев POSIX. Затем можно переопределить обработчики по умолчанию, размещенные в структурах, с помощью собственных обработчиков.
Функция resmgr_attach() копирует именно pointers в структуры resmgr_connect_funcs_t и resmgr_io_funcs_t, а не сами структуры. Следует выделить память под структуры, объявить их статическими или сделать их глобальными переменными. Если менеджер ресурсов предназначен для более чем одного устройства с разными обработчиками, следует создать отдельные структуры, которые определяют обработчики. |
В наиболее общем случае последний аргумент, handle - это произвольная структура, которую требуется связать с присоединяемым путем. На практике, однако, рекомендуется, чтобы он содержал четко определенную структуру атрибутов уровня POSIX, iofunc_attr_t, потому что это позволяет использовать библиотеку по умолчанию для уровня POSIX. Можно расширить данные, содержащиеся в структуре атрибутов, чтобы они содержали любые данные для конкретного устройства, которые могут понадобиться.
Чтобы использовать библиотеку по умолчанию уровня POSIX, структура атрибутов должна быть связана с OCB, и тогда следует использовать OCB iofunc_ocb_t уровня POSIX. Это описано в документации для resmgr_open_bind(), а также в приведенной выше ссылке.
Аргумент flags
Аргумент flags функции resmgr_attach() содержит дополнительную информацию для управления разрешением пути.
Не стоит путать эти flags с теми, что устанавливаются в поле flags структуры resmgr_attr_t. Имена этих флагов начинаются с подчеркивания (_). |
Флаги (определенные в <sys/resmgr.h>
) включают в себя как минимум следующие биты:
_IO_CONNECT
содержит путь, переданный клиентскому вызову open() с удаленным совпавшим префиксом. Без этого флага имя пути рассматривается как простой файл, требующий точного совпадения. Прикрепленный путь | Открытый путь | _RESMGR_FLAG_DIR установлен | _RESMGR_FLAG_DIR сброшен |
---|---|---|---|
/a/b | /a/b | Совпадение "" | Совпадение "" |
/a/b | /a/b/c | Совпадение c | Нет совпадения |
/a/b | /a/b/c/d | Совпадение c/d | Нет совпадения |
/a/b | /a/bc | Нет совпадения | Нет совпадения |
Существующий путь | Новый путь | Разрешен ли новый путь? |
---|---|---|
Директория /a/b | Директория /a | Да |
Директория /a/b | Директория /a/b/c | Да |
Файл /a/b | Директория /a | Да |
Файл /a/b | Директория /a/b/c | Нет; каталог находится под файлом |
Директория /a/b | Файл /a | Нет; каталог находится под файлом |
Директория /a/b | Файл /a/b/c | Да |
Файл /a/b | Файл /a | Да |
Файл /a/b | Файл /a/b/c | Да |
FTYPE_ALL
. NULL
. Следует быть осторожным при установке флага _RESMGR_FLAG_SELF , поскольку возможна взаимная блокировка (deadlock). |
Уникальный идентификатор ссылки данной связи.
Если возникла ошибка функция возвращает -1
, код ошибки записывается в errno.
Возвращенный идентификатор необходим для последующего отвязывания пути с помощью resmgr_detach(). Идентификатор также передается в resmgr_handler() как ctp->id.
Пример простого однопоточного менеджера ресурсов:
#include <stdio.h>#include <stddef.h>#include <stdlib.h>#include <sys/iofunc.h>#include <sys/dispatch.h>static resmgr_connect_funcs_t connect_funcs;static resmgr_io_funcs_t io_funcs;static iofunc_attr_t attr;int main( int argc, char **argv ){dispatch_t *dpp;resmgr_attr_t resmgr_attr;resmgr_context_t *ctp;int id;/* initialize dispatch interface */if ( (dpp = dispatch_create()) == NULL ){fprintf( stderr, "%s: Unable to allocate dispatch handle.\n", argv[0] );return (EXIT_FAILURE);}/* initialize resource manager attributes */memset( &resmgr_attr, 0, sizeof resmgr_attr );resmgr_attr.nparts_max = 1;resmgr_attr.msg_max_size = 2048;/* initialize functions for handling messages */iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &connect_funcs,_RESMGR_IO_NFUNCS, &io_funcs );/* initialize attribute structure */iofunc_attr_init ( &attr, S_IFNAM | 0666, 0, 0 );/* attach our device name (passing in the POSIX defaultsfrom the iofunc_func_init and iofunc_attr_init functions) */if ( (id = resmgr_attach( dpp, &resmgr_attr, "/dev/mynull", _FTYPE_ANY, 0,&connect_funcs, &io_funcs, &attr )) == -1 ){fprintf( stderr, "%s: Unable to attach name.\n", argv[0] );return (EXIT_FAILURE);}/* allocate a context structure */ctp = resmgr_context_alloc( dpp );/* start the resource manager message loop */while ( 1 ){if ( (ctp = resmgr_block( ctp )) == NULL ){fprintf( stderr, "block error\n" );return (EXIT_FAILURE);}resmgr_handler( ctp );}}
Другие примеры, использующие интерфейс диспетчера см. на страницах dispatch_create(), message_attach(), и thread_pool_create().
ЗОСРВ «Нейтрино»
Если приложение вызывает эту функцию, оно должно запускаться от имени пользователя root.
resmgr_attr_t, dispatch_create(), iofunc_attr_init(), iofunc_attr_t, iofunc_func_init(), iofunc_ocb_t, resmgr_block(), resmgr_connect_funcs_t, resmgr_context_alloc(), resmgr_context_free(), resmgr_detach(), resmgr_handler(), resmgr_io_funcs_t
Предыдущий раздел: Описание API системной библиотеки