if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) (
return (ENOSYS);
}
// Выяснить, сколько байт осталось...
nleft = ocb->attr->nbytes — ocb->offset;
// ...и сколько мы можем возвратить клиенту
nbytes = min(nleft, msg->i.nbytes);
if (nbytes) {
// Создать ответную строку
string = ocb->attr->inode - 1 + "A";
// Возвратить ее клиенту
MsgReply(ctp->rcvid, nbytes, &string + ocb->offset,
nbytes);
// Обновить флаги и смещение
ocb->attr->flags |=
IOFUNC_ATTR_ATIME | IOFUNC_ATTR_DIRTY_TIME;
ocb->offset += nbytes;
} else {
// Возвращать нечего, индицировать конец файла
MsgReply(ctp->rcvid, EOK, NULL, 0);
}
// Уже ответили сами
return (_RESMGR_NOREPLY);
}
Вспомогательная подпрограмма
struct dirent
, с учетом ограничений по выравниванию. Опять же, для нашего простого администратора ресурсов здесь имеет место небольшое искусственное упрощение, потому что мы точно знаем, каков размер каждого элемента каталога — все имена файлов имеют длину ровно один байт. Однако, как бы там ни было, это все равно полезная служебная подпрограмма.int dirent_size(char *fname) {
return (ALIGN(sizeof(struct dirent) - 4 + strlen(fname)));
}
И, наконец, вспомогательная подпрограмма
struct dirent* dirent_fill(struct dirent *dp, int inode,
int offset, char *fname) {
dp->d_ino = inode;
dp->d_offset = offset;
strcpy(dp->d_name, fname);
dp->d_namelen = strlen(dp->d_name);
dp->d_reclen =
ALIGN(sizeof(struct dirent) - 4 + dp->d_namelen);
return ((struct dirent*)((char*)dp + dp->d_reclen));
}
Резюме
Написание администратора ресурсов — наиболее сложная задача из описанных в этой книге.
Администратор ресурсов — это сервер, который воспринимает ряд четко определенных сообщений. Эти сообщения можно подразделить на две категории:
Сообщения установления соединения
Относятся к операциям с именами путей, с их помощью можно устанавливать контекст для дальнейшей работы.
Сообщения ввода/вывода
Всегда следуют
Действия администратора ресурса управляются функциями пула потоков (мы обсуждали их в главе «Процессы и потоки») и функциями интерфейса диспетчеризации.
QSSL в библиотеке администратора ресурсов предоставляет ряд вспомогательных POSIX-функций, которые выполняют львиную долю работы по обслуживанию клиентских сообщений установления соединения и ввода/вывода, поступающих в администратор ресурсов.
Существует ряд структур данных, относящихся к клиентам и объявляемым администраторами ресурсов устройствам, которые необходимо принимать во внимание:
OCB (блок открытого контекста)
Выделяется при каждом «открытии» ресурса; содержат контекст для клиента (например, текущее смещение
Атрибутная запись
Выделяется для каждого устройства; содержит информацию об устройстве (например, размер устройства, режимы доступа, и т.д.).
Запись точки монтирования
Распределяется на базисе по каждому администратору ресурса и содержит полную информацию о характеристиках администратора ресурса.
Клиент общается с администраторами ресурсов посредством обмена сообщениями, разрешив имя пути (с помощью функции
И наконец, вы наделяете администратор ресурса необходимой вам функциональностью, переопределяя некоторые из вызовов в таблицах функций установления соединения и функций ввода/вывода.
Приложение А
Переход с QNX4 на QNX/Neutrino
Бьерн Страуструп , Бьёрн Страуструп , Валерий Федорович Альмухаметов , Ирина Сергеевна Козлова
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT