NEXT UP previous
Next: Changing File Attributes

Inodes

You have already seen that all the files and devices in a Linux system have an inode associated with them, through which they are accessed. The mode itself contains quite a lot of information related to the file, including:

With the exception of the last item, the values of all these attributes are readily available to a process if it knows the pathname to the file or if it has a file descriptor to an open file description associated with it.

In order to access them, the status attributes that are available to a process are copied into a struct stat, which is defined via <sys/stat.h>. The main fields in this structure are:

	dev_t	st_dev;	                       /* device number	*/
	ino_t	st_ino;	                         /* mode number	*/
	umode_t	st_mode;	   /* file type and permissions	*/
	nlink_t	st_nlink;	                  /* link count	*/
	uidt	st_uid;	                    /* owner ID of file	*/
	gid_t	st_gid;		            /* group ID of file	*/
	dev_t	st_rdev	      /* device numbers for device file */
	off_t	st_size;		 /* file size, in bytes	*/
	time_t	st_atime;		 /* time of last access	*/
	time_t	st_mtime	   /* time of last modification	*/
	time_t	st_ctime;	  /* time of last status change	*/

Symbolic constants giving values for the st_mode field in this structure are defined via <sys/stat.h>.

The information in this structure can be recovered using one of the three system calls fstat(), stat() or lstat():

	#include <sys/stat h>
	#include <unistd h>

	int fstat(int fd, struct stat *sbuf); 
	int stat(char *patbname, struct stat *sbuf); 
	int lstat(char *pathname, struct stat *sbuf);

For fstat(), the fd parameter is a file descriptor to an open file description and sbuf is a pointer to a struct stat which will be filled with the appropriate status details by the call.

The stat() call is the same as fstat() except that the first parameter is the pathname to the file and not a file descriptor.

The lstat() call is the same as stat() except that if the file is a symbolic link lstat() will give the status details about the link file itself, whereas stat() will follow the link and give details about the file to which the link points.

All three system calls return 0 on successful completion, or -1 on error, with errno set to an appropriate value.

The following code is a simple program which will display human readable versions of the information in the struct stat associated with any given file pathnames:

	#include <stdio.h>
	#include <sys/stat.h>

	#define MAJOR(a) (int)((unsigned short) (a) » 8)
	#define MINOR(a) (int)((unsigned short) (a) & OxFF)

	main(int argc, char **argv) 
	{
		struct stat sbuf; int dev_flag;

		for (; argc>1; --argc)
		{			
			printf("\nFile name: Xs\n", argv[argc-1]);

			if (stat(argv[argc-1], &sbuf)==-1) 
				fatal("obtaining status details");

			dev_flag = file_type(&sbuf); 
			printf("Permission bits: %o\n", sbuf.st_mode & 07777); 
			printf("File numbers: ");
			printf("major %d, ", MAJOR(sbuf.st_dev)); 
			printf("minor %d, ", MINOR(sbuf.st_dev)); 
			printf("inode %d\n", sbuf.st_ino); 
			printf("Link count: %\n", sbuf.st_nlink);

			if (dev_flag)
			{
				printf("Device numbers: "); 
				printf ("major %d, ", MAJOR(sbuf.st_rdev)); 
				printf ("minor %d\n", MINOR(sbuf.st_rdev));
			}
			else
				printf("File size: %ld\n", sbuf.st_size);
			printf("File owner ID: %d\n", sbuf.st_uid); 
			printf("File group ID: %d\n", sbuf.st_gid);
		}
	}


	file_type(struct stat *sbufp)
	{
		printf("File type: ");

		switch (sbufp->st~mode & S_IFMT)
		{
			case S_IFREG:
				printf("Ordinary file\n"); 
				return 0;

			case S_IFDIR:
				printf ("Dlrectory\n"); 
				return 0;

			case S_IFIF0:
				printf("Named pipe (FIFO)\n"); 
				return 0;

			case S_IFBLK:
				printf("Block device special file\n"); 
				return 1;

			case S_IFCHR:
				printf("Character device special file\n"); 
				return 1;

			default:
				printf("Unknown... \n");
				exit(1)
		}
	}


	fatal(char *mess)
	{

		fprintf(stderr, "Error: %s\n", mess); 
		exit(i);
	}

Notice that the program is capable of dealing with multiple file names on the command line. Typical output from the program appears as follows:

	$ file_status /etc ./book.ps /dev/modem

	File name: /dev/modem
	File type: Character device special file
	Permission bits: 660
	File numbers: major 3, minor 65, mode 47638
	Link count: 1
	Device numbers: major 5, minor 64
	File owner ID: 0
	File group ID: 14
	
	File name: ./book.ps
	File type: Ordinary file
	Permission bits: 644
	File numbers: major 3, minor 66, mode 34876
	Link count: 1
	File size: 1049173
	File owner ID: 500
	File group ID: 500
	
	File name: /etc
	File type: Directory
	Permission bits: 755
	File numbers: major 3, minor 65, mode 45701
	Link count: 8
	File size: 2048
	File owner ID: 0
	File group ID: 0

NEXT UP previous
Next: Changing File Attributes