sturct stat 结构体中 st_mode 的含义

工作中遇到

else if( (s_buf.st_mode&S_IFMT) == S_IFDIR) return 2;

else if( !(s_buf.st_mode&S_IFREG) || access(file, W_OK) == -1) return 0;

return 1;     来了解一下stat结构体

sturct stat 结构体中 st_mode 的含义

2013-03-15 22:02 4346人阅读 评论(5) 收藏 举报

 分类:

系统编程(17) 

在<sys/stat.h>中定义的stat结构体内容如下:

[cpp] view plain copy

print?

  1. struct stat {
  2. dev_t     st_dev;     /* ID of device containing file */
  3. ino_t     st_ino;     /* inode number */
  4. mode_t    st_mode;    /* protection */
  5. nlink_t   st_nlink;   /* number of hard links */
  6. uid_t     st_uid;     /* user ID of owner */
  7. gid_t     st_gid;     /* group ID of owner */
  8. dev_t     st_rdev;    /* device ID (if special file) */
  9. off_t     st_size;    /* total size, in bytes */
  10. blksize_t st_blksize; /* blocksize for file system I/O */
  11. blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
  12. time_t    st_atime;   /* time of last access */
  13. time_t    st_mtime;   /* time of last modification */
  14. time_t    st_ctime;   /* time of last status change */
  15. };

本文着眼于st_mode成员,该成员描述了文件的类型和权限两个属性。

st_mode是个32位的整型变量,不过现在的linux操作系统只用了低16位(估计是鉴于以后拓展的考虑)。

===============================================================================================================

先看File type属性区域,位于bit12 ~ bit15.

在现代linux操作系统上文件类型共分为7种,分别是:

普通文件(regular file)

目录(directory)

字符设备(character device)

块设备(block device)

管道(FIFO<pipe>)

符号链接文件(symbolic link)

套接口文件(socket)

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

在<sys/stat.h>中有如下定义:

[cpp] view plain copy

print?

  1. #define S_IFMT  00170000
  2. #define S_IFSOCK 0140000
  3. #define S_IFLNK  0120000
  4. #define S_IFREG  0100000
  5. #define S_IFBLK  0060000
  6. #define S_IFDIR  0040000
  7. #define S_IFCHR  0020000
  8. #define S_IFIFO  0010000
  9. #define S_ISUID  0004000
  10. #define S_ISGID  0002000
  11. #define S_ISVTX  0001000
  12. #define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
  13. #define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
  14. #define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
  15. #define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
  16. #define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
  17. #define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)
  18. #define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)

首先S_IFMT是一个掩码,它的值是017000(注意这里用的是八进制), 可以用来过滤出前四位表示的文件类型。

其后的连续七个分别对应套接口文件、符号链接文件、普通文件、块设备、目录、字符设备、管道,它们分别对应一个不同的值。

现在假设我们要判断一个文件是不是目录,我们怎么做呢?

很简单,首先通过掩码S_IFMT把其他无关的部分置0,再与表示目录的数值比较,从而判断这是否是一个目录,下面的代码:

[cpp] view plain copy

print?

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

为了简便操作,<sys/stat.h>中提供了宏来代替上述代码,所以如果需要判断文件是不是目录就可以这样:

[cpp] view plain copy

print?

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

===============================================================================================================

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

在<sys/stat.h>有如下定义:

[cpp] view plain copy

print?

  1. #define S_IRWXU 00700   /* mask for file owner permissions */
  2. #define S_IRUSR 00400   /* owner has read permission */
  3. #define S_IWUSR 00200   /* owner has write permission */
  4. #define S_IXUSR 00100   /* owner has execute permission */
  5. #define S_IRWXG 00070   /* mask for group permissions */
  6. #define S_IRGRP 00040   /* group has read permission */
  7. #define S_IWGRP 00020   /* group has write permission */
  8. #define S_IXGRP 00010   /* group has execute permission */
  9. #define S_IRWXO 00007   /* mask for permissions for others (not in group) */
  10. #define S_IROTH 00004   /* others have read permission */
  11. #define S_IWOTH 00002   /* others have write permission */
  12. #define S_IXOTH 00001   /* others have execute permission */

程序中可以自由组合使用它们。

值得一提的是,目录的权限与普通文件的权限是不同的。目录的读、写、执行权限含义分别如下:

(1)读权限。读权限允许我们通过opendir()函数读取目录,进而可以通过readdir()函数获得目录内容,即目录下的文件列表。

(2)写权限。写权限代表的是可在目录内创建、删除文件,而不是指的写目录本身。

(3)执行权限。可访问目录中的文件。

===============================================================================================================

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

来自:http://blog.csdn.net/astrotycoon/article/details/8679676

时间: 2024-08-27 07:42:45

sturct stat 结构体中 st_mode 的含义的相关文章

file结构体中private_data指针的疑惑【转】

本文转载自:http://www.cnblogs.com/pengdonglin137/p/3328984.html hi all and barry, 最近在学习字符设备驱动,不太明白private_data在字符驱动中的作用,我们在 驱动中添加一个设备结构体,然后定义了这个结构体的全局指针变量,接着我们就能在 驱动程序中使用这个指针了.我看到很多驱动程序中都把结构体指针付给private_data, 然后对private_data操作. 为什么要使用private_data,难道仅仅是避免使

SCROLLINFO结构体中fMask和nPage的理解

还是VC++中有关显示图像的问题. 我们在显示一幅比较大的图像时,要使用带标准滚动条的对话框.涉及对滚动条的操作就不得不提SCROLLINFO这个结构体.只看单词意思就这道这个结构体要储存滚动条的一些信息.究竟是哪些信息呢?我们先看看这个结构体的定义: typedef struct tagSCROLLINFO { UINT cbSize ; // SCROLLINFO结构体长度的字节数 UINT fMask ; // 指定结构体中哪些成员有效 int nMin;   // 滚动范围最小尺寸 in

结构体中的数据对齐

c语言结构中需要注意的就是数据存储的对齐方式. 对齐的好处:对齐主要是为了方便数据的访问,提高计算机的处理速度,但同时它会浪费内存空间. CPU的优化规则大致是这样的:对于n字节的元素,它的首地址能被n整除,才能获得最好的性能. 对齐的使用原则: 1.一般的基本对齐原则是按着最大的基本类型的长度进行对齐.较小的元素可以组合起来填充一段内存,实现基本的对齐.前提是其满足条件2. 2.结构体中的元素也要满足一定的分布条件,就是元素的存储起始地址要满足能够整除该元素类型的长度. 3.在结构体中存在结构

结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占用int长度空间,空数组不占任何空间.“这个数组不占用任何内存”,意味着这样的结构节省空间:“该数组的内存地址就和它后面的元素地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用. 这样的写法最适合制作动态buffer,因为可以这样分配空间malloc(sizeof(struc

libev 中 ev_loop 结构体中的成员变量

1.ev_loop是libev用来描述事件循环的结构体.在libev中的定义比较绕,这里把它摘抄出来,做下注释,方便学习.libev的定义如下 struct ev_loop { ev_tstamp ev_rt_now; #define ev_rt_now ((loop)->ev_rt_now) #define VAR(name,decl) decl; #include "ev_vars.h" #undef VAR }; #include "ev_wrap.h"

遍历结构体中的变量

public struct Site  {  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]  public string Country;     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]  public string StationNumber;     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]  publi

结构体中函数指针与typedef关键用途(函数指针)

// 结构体函数指针.  #include<stdio.h> //为了代码的移植考虑,一般使用typedef定义函数指针类 ,另一个好处是,减少代码的书写量.  typedef void (*shout)(char *name,int age); typedef struct {  //用指针来存储字符串     char *name;    int age ;    shout personinfo; }person; //类似于c++中类方法的实现,在这里,是为结构体中指针函数提供实现.在

结构体中的位域

在储存信息时,有时并不需要一个字节的空间而是只需要几个二进制位就足够了.因此在C语言中为了节省空间提高效率,因此引出了位域(也叫位段)的概念. 如下代码中: #include<stdio.h> typedef struct Test { char a : 1; char b : 1; char c : 1; }Test; void main() { printf("sizeof(Test) = %d\n",sizeof(Test)); } a,b,c都是字符类型,而每个字符

对于结构体中内存对齐的简单说明

结构体内存对齐的原因: 在运行一个结构体时,编译器需要给结构体中的每个变量成员分配内存空间,如这样一个结构体中 typedef struct A { char c1; int i; int j; }A; 对其内存空间分配问题进行分析,如若不进行内存对齐,它的内存空间是: char类型变量c1占1个字节,紧接着int类型变量i与j分别占4个字节,总有9个字节,在访问时,如图1,访问次数较多:在图2中,总有12个字节空间,虽然浪费了c1后的三个字节空间,访问次数却变少,会很大程度上节省了时间,提高了