Handling the xtype member
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.
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