struct stat
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:
- struct __stat_t32_2001
- Includes 32-bit time_t fields, but not the nanosecond-resolution timestamps. This is what earlier versions of the OS supported and is the default for 32-bit architectures.
- struct __stat_t32_2008
- Includes 32-bit time_t fields, and the nanosecond-resolution timestamps.
- struct __stat_t64_2008
- Includes 64-bit time_t fields, and the nanosecond-resolution timestamps. This is the default for 64-bit architectures.
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:
- dircntl()
- Use these flags (defined in <dirent.h>) to indicate which form of stat
structure you want returned with readdir():
#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 0x000000f0If 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.
- _readdir_r()
- If D_FLAG_STAT is set, set _IO_XFLAG_DIR_EXTRA_HINT in the
_IO_READ message's xtype.
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, - _IO_READ handler
- Append the appropriate form of the stat structure to the message, setting d_type
(in dirent_extra_stat) to one of the following (from <dirent.h>):
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 }; - _IO_STAT messages
- Choose the appropriate type (from <sys/stat.h>):
#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) #endifThere's a mask too:
#define _STAT_FORM_MASK 0x03uThe handler returns, via the status argument to MsgReply(), the format that was generated.
