Вход/Регистрация
Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
вернуться

Кёртен Роб

Шрифт:

• поддерживание контекстной информации (индекс lseek);

• обновление POSIX-информации stat.

Учет размеров областей данных

В нашем случае администратор ресурсов возвращает фиксированную строку длиной в 17 байт, то есть размер доступных данных точно известен и постоянен. Эти аналогично случаю с дисковым файлом, доступным только для чтения и содержащим рассматриваемую строку. Единственное реальное отличие состоит в том, что этот «файл» обеспечивается в нашей программе строкой:

char *data_string = "Здравствуй, мир!\n";

С другой стороны, клиент может запросить чтение любого объема данных — один байт, 17 байт или более. Это должно отразиться на характеристиках вашей реализации io_read ее умением согласовывать размер запрашиваемых клиентом данных с размером данных, имеющихся в наличии.

Обработка EOF

Особым случаем согласования размеров областей данных является обработка EOF для строки фиксированной длины. Как только клиент считал заключительный символ «

\n
», дальнейшие его попытки считать данные должны возвращать EOF.

Поддерживание контекстной информации

И «учет размеров областей данных», и «обработка EOF» требуют, чтобы в OCB, передаваемом вашей функции io_read, поддерживалась контекстная информация — в частности, поле offset.

Обновление информации POSIX

И еще одно заключительное соображение: при чтении данных из ресурса должна обновляться POSIX-переменная времени доступа atime («access time» — «время доступа»). Это делается для того, чтобы клиентская функция stat могла обнаружить, что к устройству кто-то обращался.

Собственно код

Ниже приведена программа, в которой учтены все вышеперечисленные моменты. Ниже мы ее последовательно проанализируем.

/*

 * io.read1.c

*/

#include <stdio.h>

#include <errno.h>

#include <sys/neutrino.h>

#include <sys/iofunc.h>

// наша строка с данными

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;

  • Читать дальше
  • 1
  • ...
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: