Instead of returning just the struct dirent in the _IO_READ message, you can also return a struct stat. Although this will improve efficiency, returning the struct stat is entirely optional. If you don't return one, the users of your device will then have to call stat() or lstat() to get that information. (This is basically a usage question. If your device is typically used in such a way that readdir() is called, and then stat() is called, it will be more efficient to return both. See the documentation for readdir() in the QNX Neutrino C Library Reference for more information.)
The client can set the xtype member of the message to _IO_XFLAG_DIR_EXTRA_HINT to send a hint to the filesystem to return the extra information, however the filesystem isn't guaranteed to do so. If the resource manager provides the information, it must put it in a struct dirent_extra_stat, which is defined as follows:
struct dirent_extra_stat { uint16_t d_datalen; uint16_t d_type; uint32_t d_reserved; struct stat d_stat; };
The resource manager must set d_type to the appropriate _DTYPE_LSTAT* or _DTYPE_STAT* value, depending on whether or not it resolves symbolic links, whether the information is for a 32- or 64-bit architecture, and which version of POSIX is being used (see readdir()). For example:
if(msg->i.xtype & _IO_XFLAG_DIR_EXTRA_HINT) { struct dirent_extra_stat extra; extra.d_datalen = sizeof extra.d_stat; extra.d_type = _DTYPE_LSTAT; extra.d_reserved = 0; iofunc_stat(ctp, &attr, &extra.d_stat); ... }
There's a dirent_extra_stat after each directory entry:
The client has to check for extra data by using the _DEXTRA_*() macros (see the entry for readdir() in the QNX Neutrino C Library Reference.) If this check fails, the client will need to call lstat() or stat() explicitly. For example, ls -l checks for extra _DTYPE_LSTAT information; if it isn't present, ls calls lstat(). The ls -L command checks for extra _DTYPE_STAT information; if it isn't present, ls calls stat().