Read I/O function handler

QNX SDP8.0Getting Started with the QNX OSDeveloperUser

Prototype:

int (*read) ( resmgr_context_t *ctp,
              io_read_t *msg,
              RESMGR_OCB_T *ocb ) 

Classification:

I/O

Default handler:

iofunc_read_default()

Helper functions:

iofunc_read_verify()

Client functions:

read(), readdir()

Messages:

_IO_READ, _IO_READ64

Data structure:

struct _io_read {
    uint16_t            type;
    uint16_t            combine_len;
    uint32_t            nbytes;
    uint32_t            xtype;
    uint32_t            zero;
};

struct _io_read64 {
    uint16_t            type;
    uint16_t            combine_len;
    uint32_t            nbytes;
    uint32_t            xtype;
    uint32_t            nbytes_hi;
};

typedef union {
    struct _io_read     i;
    struct _io_read     i64;
    /* unsigned char    data[nbytes];    */
    /* nbytes is returned with MsgReply  */
} io_read_t;

Description:

Responsible for reading data from the resource. The client specifies how many bytes it's prepared to read in the nbytes input member. You return the data, advance the offset in the OCB, and update the appropriate time fields.

Note the following:

  • The client library uses the _IO_READ64 form only when the length is greater than 4 GB. You can use the _IO_READ_GET_NBYTES() macro (defined in <sys/iofunc.h>) to determine the number of bytes.
  • The xtype member may specify a per-read-message override flag. This should be examined. If you don't support any extended override flags, you should return an EINVAL. We'll see the handling of one particularly important (and tricky!) override flag called _IO_XTYPE_OFFSET in the read I/O function handler and write I/O function handler examples below.
  • The _IO_READ or _IO_READ64 message arrives not only for regular files, but also for reading the contents of directories. You must ensure that you return an integral number of struct dirent members in the directory case. For more information about returning directory entries, see the example in the Advanced topics section under Returning directory entries.
  • The readdir() function sets xtype to _IO_XTYPE_READDIR. Your handler for this message can give an error if someone tries to read() from a directory.

You should call the helper function iofunc_read_verify() to ascertain that the file was opened in a mode compatible with reading. You should also call the iofunc_sync_verify() function to verify if the data needs to be synchronized to the medium. (For a read(), that means that the data returned is guaranteed to be on-media.)

Returns:

The number of bytes read, or the status, via the helper macro _IO_SET_READ_NBYTES(), and the data itself via message reply. For an example of returning just data, take a look at A simple read I/O function handler example below. For a more complicated example of returning both data and directory entries, look in the Advanced topics section under Returning directory entries.

Referenced by:

resmgr_io_funcs_t I/O table

Permission checking:

The default implementation iofunc_read_default() calls iofunc_read_verify() and then doesn't return any data. Because it is possible to open a file without read or write permissions, you must validate that the OCB was opened for read in each call. The iofunc_read_verify() function does this by default. Also, the resource manager should validate the extended type; see If you aren't expecting extended types (xtype) in Writing a Resource Manager).

Page updated: