免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3363 | 回复: 1
打印 上一主题 下一主题

unix/linux文件属性及其系统调用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-07 21:12 |只看该作者 |倒序浏览
本帖最后由 j3kljs02398j 于 2011-09-07 21:15 编辑

TABLE
1. 获取文件属性(stat,fstat,lstat)
2. 文件类型
        2.1 文件类型包括一下几种
        2.2 文件类型测试的宏
        2.3 文件类型测试实例
3. 文件的权限
        3.2 关于权限的小细节
        3.3 设置用户ID和设置组ID
        3.4 文件权限操作的系统调用
        3.4.1 umask函数
        3.4.2 chmod和fchmod
        3.4.3 chown fchown和lchown  
4. 文件的时间
        4.1 utime函数



        文件有其属性,如类型,权限,长度,状态等,本文将对此进行总结,同时学习相关的系统调用。

1. 获取文件属性(stat,fstat,lstat)
        三个stat函数能够返回文件的信息。

  1. #include <sys/stat.h>

  2. int stat(const char *pathname, struct stat *buf);
  3. int fstat(int filedes, struct stat *buf);
  4. int        lstat(const char *pathname, struct stat *buf);
  5. 返回值:成功        0
  6.                 失败        -1
复制代码
三个函数的区别是,stat 第一个参数是文件名,fstat 第一个参数文件描述符,lstat 第一参数是文件名,且他返回的是符号链接的信息,而不是符号链接引用文件的信息。
        第二个参数buf结构体指针,是一个我们必须提供的结构。其基本的形式:
        struct stat {
                mode_t        st_mode;        /* 文件类型和文件权限 */
                ino_t        st_ino;                /* 与该文件关联的inode */
                dev_t        st_dev;                /* 保存的文件设备 */
                nlink_t st_nlink;        /* 该文件上硬链接的个数 */
                uid_t        st_uid;                /* 文件属主UID */
                gid_t        st_gid;                /* 文件属主GID */
                off_t        st_size;        /* 文件字节数,普通文件有效 */
                time_t        st_atime;        /* 文件上一次被访问的时间 */
                time_t st_mtime;        /* 文件内容上一次被修改的时间 */
                time_t        st_ctime;        /* 文件权限、属主、组或内容上一次被修改的时间 */
        }
        使用stat函数最多的可能是`ls -l`命令,来获取一个文件的所有信息。下面我们就按照stat的内容来了解文件属性信息。

2. 文件类型
        结构体stat的st_mode里就有文件类型的信息(st_mode同时包含文件类型和文件权限)。
        2.1 文件类型包括一下几种
        1. 普通文件/regular file。
        最长用的文件类型。数据可以是文本也可以是二进制文件,对unix内核来说没有区别。
        2. 目录文件/directory file。
        这种文件包含了其他文件的名字和指向这些文件有关信息的指针。
        3. 块特殊文件/block special file。
        这种文件类型提供对设备带缓冲的访问。每次访问以固定长度为单位进行。
        4. 字符特殊文件/ character special file
        这种文件类型提供对设备不带缓冲的访问。每次访问长度可变。
        5. FIFO
        这种类型文件用于进程间通信,也成为命名管道。
        6. 套接字 / socket
        这种文件类型用于进程间的网络通信。
        7. 符号链接 / sysbolic link
        这种类型文件指向另一个文件。

        2.2 文件类型测试的宏
        对于一个文件,可以用下面的宏来确定文件类型。这些宏的参数是 stat中的st_mode成员。
        S_ISREG()        测试是否是普通文件
        S_ISDIR()        测试是否是目录文件
        S_ISBLK()        测试是否是块特殊文件
        S_ISCHR()        测试是否是字符特殊文件
        S_ISFIFO()        测试是否管道
        S_ISSOCK()        测试是套接子
        S_ISLNK()        测试是否是链接文件

        2.3 文件类型测试实例

  1. filename: file_type.c
  2. #include <unistd.h>
  3. #include <sys/stat.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>

  6. int main(int argc, char *argv[])
  7. {
  8.         int        ret;
  9.         int i;
  10.         struct stat        stat_buf;
  11.         char        *p_file_type;

  12.         for (i = 1; i < argc; i++) {
  13.                 if ((ret = lstat(argv[i], &stat_buf)) == -1) {
  14.                         fprintf(stderr, "%s ---> lstat error!\n", argv[i]);
  15.                         continue;
  16.                 }
  17.                 if (S_ISREG(stat_buf.st_mode))
  18.                         p_file_type = "regular";
  19.                 else if (S_ISDIR(stat_buf.st_mode))
  20.                         p_file_type = "dir";
  21.                 else if (S_ISCHR(stat_buf.st_mode))
  22.                         p_file_type = "character special";
  23.                 else if (S_ISBLK(stat_buf.st_mode))
  24.                         p_file_type = "block special";
  25.                 else if (S_ISLNK(stat_buf.st_mode))
  26.                         p_file_type = "symbolic link";
  27.                 else if (S_ISFIFO(stat_buf.st_mode))
  28.                         p_file_type = "fifo";
  29.                 else if (S_ISSOCK(stat_buf.st_mode))
  30.                         p_file_type = "socket";
  31.                 else
  32.                         p_file_type = "unknow";
  33.                 printf("%s ---> %s\n",argv[i],  p_file_type);
  34.         }

  35.         return 0;
  36. }

复制代码
测试

  1. [test@test stat_code]$ ./file_type /dev/initctl /etc/passwd /dev/sda /dev/tty /dev/log /dev/cdrom
  2. /dev/initctl ---> fifo
  3. /etc/passwd ---> regular
  4. /dev/sda ---> block special
  5. /dev/tty ---> character special
  6. /dev/log ---> socket
  7. /dev/cdrom ---> symbolic link
  8. [test@test stat_code]$
复制代码
3. 文件的权限
        st_mode里包含了针对文件的访问权限位。所有文件类型都有访问权限。

        3.1 9个访问权限位

        S_IRUSR                        用户读
        S_IWUSR                        用户写
        S_IXUSR                        用户执行

        S_IRGRP                        组读
        S_IWGRP                        组写
        S_IXGRP                        组执行

        S_IROTH                        其他组读
        S_IWOTH                        其他组写
        S_IXOTH                        其他组执行
        访问权限分为三组,用户,组,其他。每组有读、写、执行权限。

        3.2 关于权限的小细节
        1. 用名字打开任意类型的文件时,对该名字中包含的每一个目录都有要有执行权限。这就是为什么对于目录的执行权限位常被成为搜索位的原因。
        2. 要执行文件不需要一定有读权限
        3. 要输出某文件,只需要对其上级目录有执行和写权限,对其自身无要求。
         
        3.3 设置用户ID和设置组ID
        与进程相关的ID有很多,常用的有实际用户ID,实际组ID,有效用户ID,有效组ID。
        实际用户ID和实际组ID表示我们是谁。他们在登录时取自口令文件的登录项。
        有效用户ID,有效组ID决定了我们的文件访问权限。通常他们等于实际用户ID和实际组ID。
        在执行一个程序文件时,进程的有效用户ID通常就是实际用户ID,有效组ID通常是实际组ID。但可以在文件模式字(st_mode)中设置特殊标志,其含义是“当执行此文件时,将进程的有效用户ID设置为文件所有者ID(st_uID)“。相应的有设置组ID。
        例如,一个普通用户执行root的文件,而且此文件设置了用户ID位,那么进程执行时将有超级用户权限,多么危险的事情啊!
        设置用户ID和设置组ID包含在st_mode中。可以用S_ISUID和S_ISGID测试。

        3.4 文件权限操作的系统调用
        3.4.1 umask函数
        umask函数为进程设置文件模式创建屏蔽子,返回以前的值。(没有出错返回)

  1. #include <sys/stat.h>
  2. mode_t umast(mode_t cmask);
  3. 返回值:以前的文件模式创建的屏蔽字
复制代码
cmask是9个常量中的若干个位“或”构成的。简单的理解就是你不想要哪位权限那么就给他“或”上。umask(S_IWOTH| S_IWGRP),意思是禁止组写和其他组写权限。
        3.4.2 chmod和fchmod

  1. #include <sys/stat.h>
  2. int chmod(const char *pathname, mode_t mode);
  3. int fchmod(int filedes, mode_t mode);
  4. return: sucessful 0
  5.                 failed        -1
复制代码
改变一个文件的权限位,进程的有效用户必须等与文件的所有者,活着是supper user.
        mode的取值
        S_IRWXU                        用户读写执行
                S_IRUSR                        用户读
                S_IWUSR                        用户写
                S_IXUSR                        用户执行

        S_IRWXG                        组读写执行
                S_IRGRP                        组读
                S_IWGRP                        组写
                S_IXGRP                        组执行

        S_IRWXO                        其他读写执行
                S_IROTH                        其他组读
                S_IWOTH                        其他组写
                S_IXOTH                        其他组执行

        S_ISUID                        执行时设置用户ID
        S_ISGID                        执行时设置组ID
        S_ISVTX                        没讨论

        相对于以前常用的9个多了6个,三个全包含的,两个设置ID和一个粘住位(不讨论)。
        3.4.3 chown fchown和lchown

  1. #include <unistd.h>
  2. int chown(const char *pathname, uid_t owner, gid_t group);
  3. int fchown(int filedes, uid_t owner, gid_t group);
  4. int lchown(const char *pathname, uid_t owner, gid_t group);
  5. return: sucessful 0
  6.                 failed        -1
复制代码
除了所引用的文件是符号链接外,这三个函数操作相似。符号链接的情况下,lchown改变的是符号链接本身,不是他指向的文件。

4. 文件的时间
        与每个文件相关的三个时间值
        st_atime        文件数据的最后访问时间
        st_ctime        文件i节点的最后更改时间
        st_mtime        文件数据最后更改时间
        4.1 utime函数

  1. #include <utime.h>
  2. int utime(const char *pathname, const struct utimebuf *times);
  3. return: sucessful        0
  4.                 failed        -1
复制代码

  1. struct utimebuf {
  2.         time_t        actime;
  3.         time_t        modtime;
  4. }
复制代码
a. 当times为NULL,则访问时间和修改时间都设为当前时间
        b. times不空,访问时间和修改时间修改
        st_ctime,不能被修改,当utime成功返回后, st_ctime自动更新。
link:http://blog.chinaunix.net/space. ... blog&id=2748100

论坛徽章:
1
射手座
日期:2014-08-04 16:49:43
2 [报告]
发表于 2011-09-08 15:45 |只看该作者
还能说什么呢,,顶呗.......
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP