Introduction to the stat family of functions

    The stat family of functions can be used to obtain the structural meta-information of a file, mainly including the following four functions:
#include <sys/stat.h>

int stat(const char *restrict pathname, struct stat *restrict buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *restrict pathname, struct stat *restrict buf);
int fstatat(int fd,const char *restrict pathname,struct stat *restrict buf,int flag);
                     /* The return values ​​of the four functions: if successful, return 0; otherwise, return -1 */

    Among them, the stat function obtains the information structure related to the file named by pathname; the fstat function obtains the information about the file that has been opened on the descriptor fd; the lstat function is similar to stat, but when the named file is a symbolic link, it obtains the Information about the symbolic link, not the referenced file.
    The fstatat function returns file statistics for a pathname relative to the currently open directory (pointed to by the fd parameter). The flag parameter controls whether a symbolic link is to be followed. When the AT_SYMLINK_NOFOLLOW flag is set, the fstatat function does not follow symbolic links, but returns information about the symbolic link itself. Otherwise, by default, information about the actual file pointed to by the symbolic link is returned. If the value of the fd parameter is AT_FDCWD and pathname is a relative pathname,
fstatat evaluates the pathname parameter relative to the current directory. If pathname is an absolute path, the fd parameter is ignored. In both cases, depending on the value of flag, fstatat acts the same as stat or lstat.
    Another parameter, buf, is the address of a stat structure, and the stat family of functions will automatically fill in the content of the structure when called. The actual definition of a structure may vary by implementation, but its basic form is:
struct stat{
    mode_t    st_mode;      // file type & mode (permissions)
    ino_t     st_ino;       // i-node number (serial number)
    dev_t     st_dev;       // device number (file system)
    dev_t     st_rdev;      // device number for special files (XSI)
    nlink_t   st_nlink;     // number of links
    uid_t     st_uid;       // user ID of owner
    gid_t     st_gid;       // group ID of owner
    off_t     st_size;      // size in bytes, for regular files
    struct timespec    st_atim;    // time of last access
    struct timespec    st_mtim;    // time of last modification
    struct timespec    st_ctim;    // time of last file status change
    blksize_t    st_blksize;    // best I/O block size (XSI)
    blkcnt_t     st_blocks;     // number of disk blocks allocated (XSI)
};

    The timespec structure type defines the time in seconds and nanoseconds, including at least the following two fields:
        time_t tv_sec;
        long tv_nsec;     st_mode
    in the stat structure contains file type information, and the file types include the following:
file). This is the most commonly used file type and contains some form of data. The UNIX kernel doesn't care if it's text or binary data, because the interpretation of the contents of a normal file is done by the file's application. One notable exception, though, is binary executables. In order to execute a program, the kernel must understand its format. All binary executables follow a standardized format so that the kernel can determine where to load program text and data.
    (2) Directory file (directory file). This file contains the names of other files and pointers to information related to those files. Any process with read permission on a directory can read the contents of the directory, but only the kernel can directly write the directory files, and the process must use a specific function to change the directory.
    (3) block special file (block special file) (note that FreeBSD no longer supports block special files, all access to the device needs to be done through character special files). This type of file provides buffered access to a device, such as a disk, with each access in units of fixed length.
    (4) Character special file (character special file). This type of file provides unbuffered access to the device, with variable length per access. All devices in the system are either character special files or block special files.
    (5) FIFO. This type of file is used for interprocess communication and is sometimes called a named pipe.
    (6) Socket (socket). This type of file is used for network communication between processes and can also be used for non-network communication between processes on a host.
    (7) Symbolic link (symbolic link). This type of file points to another file.
    The file type can be determined using the following macros, which take the st_mode member of the stat structure:
#include <sys/stat.h>

S_ISREG() // normal file
S_ISDIR() // directory file
S_ISCHR() // character special file
S_ISBLK() // block special file
S_ISFIFO() // pipe or FIFO
S_ISLNK() // symbolic link
S_ISSOCK() // socket

    In addition, POSIX.1 allows implementations to describe inter-process communication (IPC) objects such as message queues and semaphores as files. The following macros can be used to determine the type of an IPC object from a stat structure, and their argument is a pointer to a stat structure:
#include <sys/stat.h>

S_TYPEISMQ() // message queue
S_TYPEISSEM() // Semaphore
S_TYPEISSHM() // shared storage object

    Here is an example of viewing file types:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int main(int argc, char *argv[]){
	int i;
	struct stat buf;
	char * ptr;

	for(i=1;i<argc;i++){
		printf("%s: ", argv[i]);
		if(lstat(argv[i], &buf) < 0){
			printf("lstat error\n");
			continue;
		}
		if(S_ISREG(buf.st_mode))
			ptr = "regular";
		else if(S_ISDIR(buf.st_mode))
			ptr = "directory";
		else if(S_ISCHR(buf.st_mode))
			ptr = "character special";
		else if(S_ISBLK(buf.st_mode))
			ptr = "block special";
		else if(S_ISFIFO(buf.st_mode))
			ptr = "fifo";
		else if(S_ISLNK(buf.st_mode))
			ptr = "symbolic link";
		else if(S_ISSOCK(buf.st_mode))
			ptr = "socket";
		else
			ptr = "** unknown mode **";
		printf("%s\n", ptr);
	}
	exit(0);
}

    operation result:
$ ./printFileType.out /etc/passwd /etc /dev/log /dev/tty /var/lib/oprofile/opd_pipe /dev/sr0 /dev/cdrom
/etc/passwd: regular
/etc: directory
/dev/log: socket
/dev/tty: character special
/var/lib/oprofile/opd_pipe: lstat error
/dev/sr0: block special
/dev/cdrom: symbolic link

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326191221&siteId=291194637