linux C函数之stat函数

1.函数功能:

通过文件名filename获取文件信息,并保存在buf所指的结构体stat中。

2.函数原型

函数头文件

#include   
#include   

函数

int stat(const char *file_name, struct stat *buf )  

返回值:

执行成功则返回0,失败返回-1,错误代码存于errno

错误代码 说明
ENOENT 参数file_name指定的文件不存在
ENOTDIR 路径中的目录存在但却非真正的目录
ELOOP 欲打开的文件有过多符号连接问题,上限为16符号连接
EFAULT 参数buf为无效指针,指向无法存在的内存空间
EACCESS 存取文件时被拒绝
ENOMEM 核心内存不足
ENAMETOOLONG 参数file_name的路径名称太长

相关结构体

struct stat {  
    dev_t         st_dev;       //文件的设备编号  
    ino_t         st_ino;       //节点  
    mode_t        st_mode;      //文件的类型和存取的权限  
    nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1  
    uid_t         st_uid;       //用户ID  
    gid_t         st_gid;       //组ID  
    dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号  
    off_t         st_size;      //文件字节数(文件大小)  
    unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)  
    unsigned long st_blocks;    //块数  
    time_t        st_atime;     //最后一次访问时间  
    time_t        st_mtime;     //最后一次修改时间  
    time_t        st_ctime;     //最后一次改变时间(指属性)  
}; 

其中的st_mode(32位整型变量,不过现在的Linux操作系统只用了低16位。),该成员描述了文件的类型和权限两个属性。
linux C函数之stat函数_第1张图片

S_IFMT   0170000    文件类型的位遮罩  
S_IFSOCK 0140000     scoket文件(套接口文件)  
S_IFLNK  0120000     符号连接(符号链接文件)  
S_IFREG  0100000     一般文件(普通文件)  
S_IFBLK  0060000     区块装置(块设备)  
S_IFDIR  0040000     目录  
S_IFCHR  0020000     字符装置(字符设备)
S_IFIFO  0010000     先进先出(管道)  


#define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)  
#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)  
#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)  
#define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)  
#define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)  
#define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)  
#define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK) 

S_ISUID 04000     文件的(set user-id on execution)位  
S_ISGID 02000     文件的(set group-id on execution)位  
S_ISVTX 01000     文件的sticky位  

S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限  
S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限  
S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限  

S_IRGRP 00040             用户组具可读取权限  
S_IWGRP 00020             用户组具可写入权限  
S_IXGRP 00010             用户组具可执行权限  

S_IROTH 00004             其他用户具可读取权限  
S_IWOTH 00002             其他用户具可写入权限  
S_IXOTH 00001             其他用户具可执行权限 

File type属性区域,位于bit12-bit15占4位,在现代Linux操作系统上文件类型共分为7中,分别是:

普通文件(regular file)

目录(directory)

字符设备(character device)

块设备(block device)

管道(FIFO)

符号链接文件(symbolic link)

套接口文件(socket)

所以File type属性只需3bit就够了,估计也是考虑到了以后的扩展问题。

首先S_IFMT是一个掩码,它的值是0170000(注意这里使用的是八进制),可以用来过滤出12-15位的文件类型。
现在假设我们要判断一个文件是不是目录,我们怎么做呢?
很简单,首先通过掩码S_IFMT把其它无关的部分置0,再与表示目录的数值比较,从而判断这是否是一个目录,下面的代码:

if ((info.st_mode & S_IFMT) == S_IFDIR)  
    printf("this is a directory");  

为了便于操作,中提供了宏来代替上述代码,所以如果需要判断文件是不是目录也可以这样:

if (S_ISDIR(info.st_mode))  
    printf("this is a directory"); 

接着来看Permission属性区域的bit0-bit8,也即st_mode字段的最低9位,代表文件的许可权限,它标示了文件所有者(owner)、组用户(group)、其它用户(other)的读(r)、写(w)、执行(x)权限。
有如下定义:

#define S_IRWXU 00700   /* mask for file owner permissions */  
#define S_IRUSR 00400   /* owner has read permission */  
#define S_IWUSR 00200   /* owner has write permission */  
#define S_IXUSR 00100   /* owner has execute permission */  

#define S_IRWXG 00070   /* mask for group permissions */  
#define S_IRGRP 00040   /* group has read permission */  
#define S_IWGRP 00020   /* group has write permission */  
#define S_IXGRP 00010   /* group has execute permission */  

#define S_IRWXO 00007   /* mask for permissions for others (not in group) */  
#define S_IROTH 00004   /* others have read permission */  
#define S_IWOTH 00002   /* others have write permission */  
#define S_IXOTH 00001   /* others have execute permission */ 

程序中可以自由组合使用它们。
值得一提的是,目录的权限与普通文件的权限是不同的。目录的读、写、执行权限含义分别如下:
1. 读权限。读权限允许我们通过opendir()函数读取目录,进而可以通过readdir()函数获得目录内容,即目录下的文件列表。
2. 写权限。写权限代表的是可以在目录内创建、删除文件,而不是值的写目录本身。
3. 执行权限。可访问目录中的文件。

 if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH))//若具有用户执行权限或组执行权限或其它用户执行权限
            var = 1;

最后来看Permission属性区域的bit9-bit11,这三个bit比较特殊,代表文件的特殊属性,分别为set-user-ID位、set-group-ID位和sticky位。

stat,fstat,lstat函数的区别和相同点
函数原型:

#include  
#include  
int stat(const char *restrict pathname, struct stat *restrict buf);  

int fstat(int filedes, struct stat *buf);  

int lstat(const char *restrict pathname, struct stat *restrict buf);  

三个函数的返回值,若成功则为0,若出错则为-1。给定一个pathname,stat函数返回一个与此命名文件有关的信息结构,fstat函数获得已在描述符filedes上打开的文件的有关信息。lstat函数类似于stat,但是当命名的文件是一个符号连接时,lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息。

你可能感兴趣的:(Linux-C函数)