Подтвердить способность клиента открыть ресурс
#include <sys/iofunc.h>int iofunc_open( resmgr_context_t *ctp,io_open_t *msg,iofunc_attr_t *attr,iofunc_attr_t *dattr,struct _client_info *info );
NULL
или указатель на структуру iofunc_attr_t, описывающую характеристики родительского каталога.NULL
или указатель на структуру struct _client_info с информацией о клиентском подключении.libc
Функция iofunc_open() проверяет, имеет ли клиент (описываемый необязательной структурой info) доступ для открытия ресурса, имя которого передаётся в msg->connect.path.
Структура attr содержит атрибуты ресурса. Необязательная структура dattr содержит атрибуты родительского каталога; если dattr не равен NULL
, ресурс, указанный в attr, создаётся в каталоге, указанном в dattr.
Аргумент info может быть передан как NULL
, в этом случае iofunc_open() сама получает информацию о клиенте с помощью вызова iofunc_client_info(). Но, конечно, эффективнее будет получить информацию о клиенте один раз, а не каждый раз вызывать эту функцию с NULL
.
Обратите внимание, что если обрабатывается запрос на чтение/запись каталога, необходимо вернуть данные, сформированные в соответствии с типом struct dirent. Вспомогательная функция iofunc_stat() может помочь в этом.
Ответ менеджера ресурсов на запрос open() не всегда является ответом "да" или "нет". Можно вернуть сообщение о подключении, указывающее, что сервер хотел бы предпринять какое-либо другое действие. Например, если открывается символическая ссылка на какой-либо другой путь, сервер может ответить, используя макрос _IO_SET_CONNECT_RET()
и значение _IO_CONNECT_RET_LINK
.
Например, обработчик открытия только переопределяющий пути, выглядит примерно следующим образом:
io_open( resmgr_context_t *ctp, io_open_t *msg,iofunc_attr_t *dattr, void *extra ){char *newpath;/* Выполнить все проверки доступа/ошибок ... *//* Найти и сохранить новый путь в 'newpath' */newpath = get_a_new_path( msg->connect.path );_IO_SET_CONNECT_RET( ctp, _IO_CONNECT_RET_LINK );len = strlen( newpath ) + 1;msg->link_reply.eflag = msg->connect.eflag;msg->link_reply.nentries = 0;msg->link_reply.path_len = len;strcpy( (char *)(msg->link_reply + 1), newpath );len += sizeof( msg->link_reply );return (_RESMGR_PTR( ctp, &msg->link_reply, len ));}
В этом примере используется макрос _IO_RET_CONNECT_RET()
(определён в <sys/iomsg.h>
), чтобы установить в поле ctp->status значение _IO_CONNECT_REMOTE_LINK
. Это значение указывает менеджеру ресурсов, что возвращаемое значение на самом деле не является простым кодом возврата, а новым запросом, подлежащим обработке.
Путь для этого нового запроса следует непосредственно за структурой link_reply и имеет длину path_len байт. Последние несколько строк кода просто заполняют IOV ответным сообщением (и новым путём, который нужно запросить) и возвращают управление в фреймворк менеджера ресурсов.
Пример псевдокода для типичной файловой системы для шагов, которые необходимо выполнить для обработки запроса на открытие файла:
если запрос открытия пути ( т.е. несколько уровней директорий ){вызвать iofunc_client_info() чтобы получить информацию о клиенте;для каждого компонента директории{вызвать iofunc_check_access() чтобы проверить разрешения на выполнение;/** напомним, что разрешение на выполнение в каталоге на самом деле* является "поиском"*/}далее/* на этом этапе доступ подтвержден */}если O_CREAT установлен и файл не существует{вызвать iofunc_open(), передав атрибуты родительской директории как dattr;если iofunc_open() успешно завершилась{выполнить работу по созданию нового inode или чего-либо ещё;}} иначе {вызвать iofunc_open(), передав attr файла и NULL в dattr;}/* на этом этапе следует проверить o_trunc, и т.д. -- то, что необходимо сделать для attr */вызвать iofunc_ocb_attach();вернуть (EOK);
Для устройства ( resmgr_attach() не указал, что устройство является директорией), выполняются следующие действия:
/* при запуске (т.е. в main() менеджере ресурсов) */вызвать iofunc_attr_init() чтобы инициализировать структуру атрибутов;/* в обработчике сообщений io_open: */вызвать iofunc_open(), передав атрибуты устройства и NULL в dattr;вызвать iofunc_ocb_attach();вернуть (EOK);
ЗОСРВ «Нейтрино»
struct _client_info, struct dirent, io_open_t, struct _io_connect, struct _io_connect_link_reply, struct _io_connect_ftype_reply, resmgr_context_t, iofunc_attr_init(), iofunc_check_access(), iofunc_client_info(), iofunc_ocb_attach(), iofunc_stat(), open(), resmgr_attach(), resmgr_open_bind()
Предыдущий раздел: Описание API системной библиотеки