The struct stat is different in 64-bit architectures than in 32-bit ones because it includes 64-bit time_t members. POSIX 2008 added support for nanosecond-resolution timestamps (st_mtim, st_atim, and st_ctim fields are of type struct timespec). This means that there are several forms of the stat structure:
The dirent_extra_stat information (see readdir()) also handles the different stat formats. The dirent_extra_type enumerated type, which defines the possible values for the d_type member, is defined as follows:
enum dirent_extra_type { _DTYPE_NONE, _DTYPE_STAT_UNSET, _DTYPE_LSTAT_UNSET, _DTYPE_STAT_T32_2001, _DTYPE_LSTAT_T32_2001, _DTYPE_STAT_T32_2008, _DTYPE_LSTAT_T32_2008, _DTYPE_STAT_T64_2008, _DTYPE_LSTAT_T64_2008, #if __PTR_BITS__ == 32 _DTYPE_STAT = _DTYPE_STAT_T32_2001, _DTYPE_LSTAT = _DTYPE_LSTAT_T32_2001, #else _DTYPE_STAT = _DTYPE_STAT_T64_2008, _DTYPE_LSTAT = _DTYPE_LSTAT_T64_2008, #endif };
As before, the _DTYPE_STAT* types indicate that the resource manager didn't resolve symbolic links, and the _DTYPE_LSTAT* types indicate that the resource manager did. _DTYPE_STAT_UNSET and _DTYPE_LSTAT_UNSET correspond to the former values of _DTYPE_STAT and _DTYPE_LSTAT; the others also indicate which form of the stat structure is included.
You can use stat_convert_form() to convert one form of a struct stat into another.
There are several different sets of constants for identifying the formats of the stat structure:
#define D_FLAG_STAT 0x00000002 /* Attempt to return extra stat information */ #define D_FLAG_STAT_FORM_UNSET 0x00000000 /* == _STAT_FORM_UNSET */ #define D_FLAG_STAT_FORM_T32_2001 0x00000010 /* want _STAT_FORM_T32_2001 */ #define D_FLAG_STAT_FORM_T32_2008 0x00000020 /* want _STAT_FORM_T32_2008 */ #define D_FLAG_STAT_FORM_T64_2008 0x00000030 /* want _STAT_FORM_T32_2008 */
There's a mask too:
#define D_FLAG_STAT_FORM_MASK 0x000000f0
If you set a D_FLAG_STAT_FORM_* flag, it's ORed into the current flags for the directory; otherwise, the flags you pass to dircntl() replace the directory's flags. The D_FLAG_STAT_FORM_* values are the corresponding _STAT_FORM_* values shifted up four bits.
If D_FLAG_STAT_FORM_* is set, set the appropriate one of the following (from <sys/iomsg.h>) in the _IO_READ message:
_IO_XFLAG_DIR_STAT_FORM_UNSET = 0x00000000, _IO_XFLAG_DIR_STAT_FORM_T32_2001 = 0x00010000, _IO_XFLAG_DIR_STAT_FORM_T32_2008 = 0x00020000, _IO_XFLAG_DIR_STAT_FORM_T64_2008 = 0x00030000,
There's a mask too:
_IO_XFLAG_DIR_STAT_FORM_MASK = 0x000f0000,
enum dirent_extra_type { _DTYPE_NONE, _DTYPE_STAT_UNSET, _DTYPE_LSTAT_UNSET, _DTYPE_STAT_T32_2001, _DTYPE_LSTAT_T32_2001, _DTYPE_STAT_T32_2008, _DTYPE_LSTAT_T32_2008, _DTYPE_STAT_T64_2008, _DTYPE_LSTAT_T64_2008, #if __PTR_BITS__ == 32 _DTYPE_STAT = _DTYPE_STAT_T32_2001, _DTYPE_LSTAT = _DTYPE_LSTAT_T32_2001, #else _DTYPE_STAT = _DTYPE_STAT_T64_2008, _DTYPE_LSTAT = _DTYPE_LSTAT_T64_2008, #endif };
#define _STAT_FORM_UNSET 0 #define _STAT_FORM_T32_2001 1 #define _STAT_FORM_T32_2008 2 #define _STAT_FORM_T64_2008 3 #if __PTR_BITS__ == 32 #define _STAT_FORM_SYS_2008 (_STAT_FORM_T32_2008) #define _STAT_FORM_PREFERRED (_STAT_FORM_T32_2001) #else #define _STAT_FORM_SYS_2008 (_STAT_FORM_T64_2008) #define _STAT_FORM_PREFERRED (_STAT_FORM_T64_2008) #endif
There's a mask too:
#define _STAT_FORM_MASK 0x03u
The handler returns, via the status argument to MsgReply(), the format that was generated.