Чтобы проиллюстрировать, как ваш администратор ресурса мог бы возвращать клиенту данные, рассмотрим простейший администратор ресурса, который всегда возвращает одну и ту же строковую константу «Здравствуй, мир!\n
• согласование размера клиентской области данных с количеством данных, подлежащих возврату;
• обработка EOF;
• поддерживание контекстной информации (индекс
• обновление POSIX-информации
В нашем случае администратор ресурсов возвращает фиксированную строку длиной в 17 байт, то есть размер доступных данных точно известен и постоянен. Эти аналогично случаю с дисковым файлом, доступным только для чтения и содержащим рассматриваемую строку. Единственное реальное отличие состоит в том, что этот «файл» обеспечивается в нашей программе строкой:
char *data_string = "Здравствуй, мир!\n";
С другой стороны, клиент может запросить чтение любого объема данных — один байт, 17 байт или более. Это должно отразиться на характеристиках вашей реализации
Особым случаем согласования размеров областей данных является обработка EOF для строки фиксированной длины. Как только клиент считал заключительный символ «\n
И «учет размеров областей данных», и «обработка EOF» требуют, чтобы в OCB, передаваемом вашей функции
И еще одно заключительное соображение: при чтении данных из ресурса должна обновляться POSIX-переменная времени доступа
Ниже приведена программа, в которой учтены все вышеперечисленные моменты. Ниже мы ее последовательно проанализируем.
/*
* io.read1.c
*/
#include
#include
#include
#include
// наша строка с данными
char* data_string = "Здравствуй, мир!\n";
int io_read(resmgr_context_t* ctp, io_read_t* msg,
iofunc_ocb_t* ocb) {
int sts;
int nbytes;
int nleft;
int off;
int xtype;
struct _xtype_offset* xoffset;
// 1) Проверить, открыто ли устройство на чтение
if ((sts ==
iofunc_read_verify(ctp, msg, ocb, NULL)) != EOK) {
return sts;
}
// 2) проверить и обработать переопределение XTYPE
xtype = msg->i.xtype & _IO_XTYPE_MASK;
if (xtype == _IO_XTYPE_OFFSET) {
xoffset = (struct _xtype_offset*)(msg->i + 1);
off = xoffset->offset;
} else if (xtype = _IO_XTYPE_NONE) {
off = ocb->offset;
} else { // Неизвестный тип; игнорировать
return ENOSYS;
}
// 3) Сколько байт осталось?
nleft = ocb->attr->nbytes – off;
// 4) Сколько байт мы можем отдать клиенту?
nbytes = min(nleft, msg->i.nbytes);
// 5) Если возвращаем данные, отдать их клиенту
if (nbytes) {
MsgReply(ctp->rcvid, nbytes, data_string+off, nbytes);
// 6) Установить значение "atime" для POSIX stat()
ocb->attr->flags |=
IOFUNC_ATTR_ATIME | IOFUNC_ATTR_DIRTY_TIME;
// 7) Если индекс lseek() не равен _IO_XTYPE_OFFSET,
// увеличить его на число считанных байт
if (xtype == _IO_XTYPE_NONE) {
ocb->offset += nbytes;
}
} else {
// 8) Не возвращаем данные, просто разблокировать клиента
MsgReply(ctp->rcvid, EOK, null, 0);
}
// 9) Сказать библиотеке, что мы уже ответили сами
return _RESMGR_NOREPLY;
}
Бьерн Страуструп , Бьёрн Страуструп , Валерий Федорович Альмухаметов , Ирина Сергеевна Козлова
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT