- 论坛徽章:
- 0
|
本帖最后由 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函数能够返回文件的信息。
- #include <sys/stat.h>
- int stat(const char *pathname, struct stat *buf);
- int fstat(int filedes, struct stat *buf);
- int lstat(const char *pathname, struct stat *buf);
- 返回值:成功 0
- 失败 -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 文件类型测试实例
- filename: file_type.c
- #include <unistd.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <stdlib.h>
- int main(int argc, char *argv[])
- {
- int ret;
- int i;
- struct stat stat_buf;
- char *p_file_type;
- for (i = 1; i < argc; i++) {
- if ((ret = lstat(argv[i], &stat_buf)) == -1) {
- fprintf(stderr, "%s ---> lstat error!\n", argv[i]);
- continue;
- }
- if (S_ISREG(stat_buf.st_mode))
- p_file_type = "regular";
- else if (S_ISDIR(stat_buf.st_mode))
- p_file_type = "dir";
- else if (S_ISCHR(stat_buf.st_mode))
- p_file_type = "character special";
- else if (S_ISBLK(stat_buf.st_mode))
- p_file_type = "block special";
- else if (S_ISLNK(stat_buf.st_mode))
- p_file_type = "symbolic link";
- else if (S_ISFIFO(stat_buf.st_mode))
- p_file_type = "fifo";
- else if (S_ISSOCK(stat_buf.st_mode))
- p_file_type = "socket";
- else
- p_file_type = "unknow";
- printf("%s ---> %s\n",argv[i], p_file_type);
- }
- return 0;
- }
复制代码 测试
- [test@test stat_code]$ ./file_type /dev/initctl /etc/passwd /dev/sda /dev/tty /dev/log /dev/cdrom
- /dev/initctl ---> fifo
- /etc/passwd ---> regular
- /dev/sda ---> block special
- /dev/tty ---> character special
- /dev/log ---> socket
- /dev/cdrom ---> symbolic link
- [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函数为进程设置文件模式创建屏蔽子,返回以前的值。(没有出错返回)
- #include <sys/stat.h>
- mode_t umast(mode_t cmask);
- 返回值:以前的文件模式创建的屏蔽字
复制代码 cmask是9个常量中的若干个位“或”构成的。简单的理解就是你不想要哪位权限那么就给他“或”上。umask(S_IWOTH| S_IWGRP),意思是禁止组写和其他组写权限。
3.4.2 chmod和fchmod
- #include <sys/stat.h>
- int chmod(const char *pathname, mode_t mode);
- int fchmod(int filedes, mode_t mode);
- return: sucessful 0
- 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
- #include <unistd.h>
- int chown(const char *pathname, uid_t owner, gid_t group);
- int fchown(int filedes, uid_t owner, gid_t group);
- int lchown(const char *pathname, uid_t owner, gid_t group);
- return: sucessful 0
- failed -1
复制代码 除了所引用的文件是符号链接外,这三个函数操作相似。符号链接的情况下,lchown改变的是符号链接本身,不是他指向的文件。
4. 文件的时间
与每个文件相关的三个时间值
st_atime 文件数据的最后访问时间
st_ctime 文件i节点的最后更改时间
st_mtime 文件数据最后更改时间
4.1 utime函数
- #include <utime.h>
- int utime(const char *pathname, const struct utimebuf *times);
- return: sucessful 0
- failed -1
复制代码
- struct utimebuf {
- time_t actime;
- time_t modtime;
- }
复制代码 a. 当times为NULL,则访问时间和修改时间都设为当前时间
b. times不空,访问时间和修改时间修改
st_ctime,不能被修改,当utime成功返回后, st_ctime自动更新。
link:http://blog.chinaunix.net/space. ... blog&id=2748100 |
|