[LCP]typedefs in .h

Greg Black gjb at gbch.net
Sat Jan 19 13:20:56 UTC 2002


Emil Tantilov wrote:

|  I'm fairly new into C programming, in general I'm
| doing it for fun (mostly). Anyway here's my question:
| 
|  "man fstat" returns for the structure below:
| struct stat {
|   dev_t               st_dev;   
|   ino_t               st_ino;   
|   mode_t              st_mode;  
|   nlink_t             st_nlink; 
|   uid_t               st_uid;   
|   gid_t               st_gid;   
|   dev_t               st_rdev;  
|   off_t               st_size;  
|   unsigned long       st_blksize;  
|   unsigned long       st_blocks;   
|   time_t              st_atime;    
|   time_t              st_mtime;    
|   time_t              st_ctime;    
| };
| 
| Is there a fast and convinient way of finding the
| actual type (int, long, char, struct ...) for uid_t,
| dev_t, time_t, and all those types defined into the
| headers (buried to be precise)?

The answer to the actual question has now been covered fairly
well, but one thing was not made clear -- this definition of
"struct stat" is just one variant among many.  It's a system
dependent thing and you need to be careful when dealing with
it.  For example, here's the definition from a header on one of
my local boxes:

struct stat {
	__dev_t	  st_dev;		/* inode's device */
	ino_t	  st_ino;		/* inode's number */
	mode_t	  st_mode;		/* inode protection mode */
	nlink_t	  st_nlink;		/* number of hard links */
	uid_t	  st_uid;		/* user ID of the file's owner */
	gid_t	  st_gid;		/* group ID of the file's group */
	__dev_t	  st_rdev;		/* device type */
#ifndef _POSIX_SOURCE
	struct	timespec st_atimespec;	/* time of last access */
	struct	timespec st_mtimespec;	/* time of last data modification */
	struct	timespec st_ctimespec;	/* time of last file status change */
#else
	time_t	  st_atime;		/* time of last access */
	long	  st_atimensec;		/* nsec of last access */
	time_t	  st_mtime;		/* time of last data modification */
	long	  st_mtimensec;		/* nsec of last data modification */
	time_t	  st_ctime;		/* time of last file status change */
	long	  st_ctimensec;		/* nsec of last file status change */
#endif
	off_t	  st_size;		/* file size, in bytes */
	int64_t	  st_blocks;		/* blocks allocated for file */
	u_int32_t st_blksize;		/* optimal blocksize for I/O */
	u_int32_t st_flags;		/* user defined flags for file */
	u_int32_t st_gen;		/* file generation number */
	int32_t	  st_lspare;
	int64_t	  st_qspare[2];
};

As you can see, although it's clearly related to the original
above, it's quite different in some important ways and could not
be exchanged for the other definition without severe breakage.

Some of the fields are according to the POSIX specification,
some of them are extras, and some of them do dual duty (the time
fields).

Some of them will change in size as time goes by -- the size of
the off_t grows as file systems and file sizes get larger.

The time fields above provide the seconds only fields for POSIX
applications, but really record time in much smaller increments
because modern processor and clock speeds are getting too fast
for single second granularity to be useful.  This also requires
networked systems to have high quality time synchronisation
software in place.

Greg



More information about the linuxCprogramming mailing list