Handling the xtype member

QNX SDP8.0Writing a Resource ManagerDeveloper
The message structures passed to the io_read, io_write, and io_openfd handlers contain a member called xtype. From struct _io_read:
struct _io_read {
    ...
    uint32_t xtype;
    ...
}

Basically, the xtype contains extended information that can be used to adjust the behavior of a standard I/O function. This information includes a type and optionally some flags:

  • For _IO_READ and _IO_WRITE messages, the names are in the form _IO_XTYPE_* or _IO_XFLAG_*.
  • For _IO_OPENFD messages, the names are in the form _IO_OPENFD_*. The only one that you'll likely have to worry about (assuming you even want to write your own handler) is _IO_OPENFD_NONE.
To isolate the type from the flags in _IO_READ and _IO_WRITE messages, use a bitwise AND of the xtype member with _IO_XTYPE_MASK:
if ((msg->i.xtype & _IO_XTYPE_MASK) == ...)

Most resource managers care about only a few types:

_IO_XTYPE_NONE
No extended type information is being provided.
_IO_XTYPE_OFFSET
If clients are calling pread(), pread64(), pwrite(), or pwrite64(), then they don't want you to use the offset in the OCB. Instead, they're providing a one-shot offset. That offset follows the struct _io_read or struct _io_write headers that reside at the beginning of the message buffers.
For example:
struct myread_offset {
    struct _io_read        read;
    struct _xtype_offset   offset;
}

Some resource managers can be sure that their clients will never call pread*() or pwrite*(). (For example, a resource manager that's controlling a robot arm probably wouldn't care.) In this case, you can treat this type of message as an error.

_IO_XTYPE_READCOND
If a client is calling readcond(), they want to impose timing and return buffer size constraints on the read. Those constraints follow the struct _io_read or struct _io_write headers at the beginning of the message buffers. For example:
struct myreadcond {
    struct _io_read        read;
    struct _xtype_readcond cond;
}   

As with _IO_XTYPE_OFFSET, if your resource manager isn't prepared to handle readcond(), you can treat this type of message as an error.

_IO_XTYPE_READDIR
The readdir() function sets this flag in an _IO_READ message to indicate that the client is reading a directory. In your handler for this message, you could give an error of EISDIR if a client does a read() on a directory.

The following types are for special purposes, so your resource manager probably doesn't need to handle them:

  • _IO_XTYPE_MQUEUE
  • _IO_XTYPE_REGISTRY
  • _IO_XTYPE_TCPIP
  • _IO_XTYPE_TCPIP_MMSG
  • _IO_XTYPE_TCPIP_MSG
  • _IO_XTYPE_TCPIP_MSG2

The xtype member may also include some flags. Your resource manager might be interested in the following:

_IO_XFLAG_DIR_EXTRA_HINT
This flag is valid only when you're reading from a directory. The filesystem should return extra directory information when it's easy to get. If this flag is set, it's a hint to the filesystem to try harder (possibly causing media lookups) to return the extra information. The most common use is to return _DTYPE_LSTAT information.

The readdir() function sets this flag in an _IO_READ message if you've used dircntl() to set D_FLAG_STAT for the directory.

_IO_XFLAG_DIR_STAT_FORM_*
These bits specify which form of the stat structure your resource manager should return when a client reads a directory. The client can specify the form via dircntl(), and readdir() sets the flag accordingly:
dircntl() command xtype flag Structure
D_FLAG_STAT_FORM_UNSET _IO_XFLAG_DIR_STAT_FORM_UNSET The default for the 32- or 64-bit architecture that you're using
D_FLAG_STAT_FORM_T32_2001 _IO_XFLAG_DIR_STAT_FORM_T32_2001 struct __stat_t32_2001
D_FLAG_STAT_FORM_T32_2008 _IO_XFLAG_DIR_STAT_FORM_T32_2008 struct __stat_t32_2008
D_FLAG_STAT_FORM_T64_2008 _IO_XFLAG_DIR_STAT_FORM_T64_2008 struct __stat_t64_2008

You can use _IO_XFLAG_DIR_STAT_FORM_MASK to isolate these bits from the rest of the xtype.

Note:
The D_FLAG_STAT_FORM_UNSET, D_FLAG_STAT_FORM_T32_2001, and D_FLAG_STAT_FORM_T32_2008 values are legacy values for 32-bit targets and shouldn't be used in this release. Only D_FLAG_STAT_FORM_T64_2008 should be used because only 64-bit targets are supported.

The other defined flags are used for special purposes, so your resource manager probably doesn't need to handle them:

  • _IO_XFLAG_BLOCK
  • _IO_XFLAG_NONBLOCK
Page updated: