目录
一、文件操作时的权限检查规则
st mode中记录的文件权限位
st mode本质上是一个32位的数(类型就是unsinged int),这个数里的每一个位表示一个含义。
文件类型和文件的权限都记录在st_mode中。我们用的时候使用专门的掩码去取出相应的位即可得知相应的信息。
ls -1打印出权限列表
权限位共9位,3位为一组。第一组分别表示文件的属主对该文件的可读、可写、可执行权限;第2组表示文件的属主所在的组(group)对应的权限。
一个程序a.out被执行, a.out中试图去操作一个文件1.txt,这时候如何判定a.out是否具有对1.txt的某种操作权限呢?
判定方法基本是:首先1.txt具有9个权限位,规定了3种人(user、group、 others )对该文件的操作权限。所以我们判定1. txt是否能被a.out来操作, 关键先搞清楚a.out被谁执行,也就是当前程序(进程)是哪个用户的进程。
access函数检查权限设置
文本权限管控其实较为复杂,一般很难明确知道自己是否对一个文件具有某种权限。设计优秀的软件应该是:在操作某个文件之前先判断当前是否有权限进行此操作,如果有,操作就可以进行,没有则提供错误信息给用户。
access函数可以测试得到当前执行程序的用户在当前环境下对目标文件是否具有某种操作权限。
access具体手册描述如下:
根据手册描述,主要用法为int access(const char *pathname,int mode),第一个参数为文件名路径,第二个参数已给出,有F_OK,R_OK,X_OK,W_OK。
二、修改文件权限
使用chmod命令修改
(1)chmod是一个linux命令,用来修改文件的各种权限属性。chmod命令只有相应文件的才有权利去执行修改。
(2)chmod命令其实内部也是用linux的chmod的API实现的。
chown/ fchown/lchown与属主修改
(1)linux中有个chown命令来修改文件属主
(2)chown命令是用chownAPI实现的
umask与文件权限掩码
(1)文件掩码是linux系统中维护的一个全局设置,umask的作用是用来设定我们系统中新创建的文件的默认权限的。
(2)umask命令就是用umask API实现的。
touch 创建一个文件时,默认创建的文件具有的权限为 rw-rw-rw-,数字表示为0666,默认的权限值要与 umask 的取反值“按位与&”,结果才是文件的真正的权限的值。
即:真正的权限值=0666 - umask
三、读取目录文件
opendir与readdir函数
(1)opendir打开一个目录后得到一个DIR类型的指针给readdir使用。
(2)readdir函数调用一次就会返回一个structdirent类型的指针,这个指针指向一个结构体变量,这个结构体变量里面记录了一个目录项(所谓目录项就是目录中的一个子文件)。
(3)readdir调用一次只能读出一个目录项,要想读出目录中所有的目录项必须多次调用readdir函数。
readdir函数内部户记住哪个目录项已经被读过了哪个还没读,所以多次调用后不会重复返回已经返回过的目录项。当readdir函数返回NULL时就表示目录中所有的目录项已经读完了。
opendir手册如下:
readdir手册如下:
这里用到了一种结构体指针类型,用来接收读取到的目录文件内容:
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
d_ino存放文件基本信息
d_type存放文件类型
d_name存放文件名
一般情况下readdir调用一次,仅按顺序读取文件下的一个文件,顺序读完时为空NULL。
所以一般配合循环读取目录下的所有内容。
opendir与readdir联合读取目录下内容代码如下 :
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
if (argc!=2){
printf("error..\n");
return -1;
}
DIR *diropen = NULL; //目录指针
struct dirent *dirread;//结构体指针,存放目录下信息
int count = 0; //用来计算目录下的文件总数
diropen = opendir(argv[1]);
if (diropen==NULL){
perror("failed");
return -1;
} else{
printf("open success!\n");
}
while(1){
dirread=readdir(diropen);
if (dirread!=NULL){
printf("name : [%s.]\n",dirread->d_name);
count++;
} else{
break;
}
}
printf("the dir has %d files\n",count);
}
linux下编译运行结果如下:
配合使用,实现了读取目录文件的效果。
四、可重入函数介绍
(1)有些函数是可重入的有些是不可重入的。
(2) readdir函数和我们前面接触的一些函数是不同的,首先readdir函数直接返回了 (2)Readdir函数和我们前面接触的一些函数是不同的,首先Readdir函数直接返回了一个结构体变量指针,因为readdir内部申请了内存并且给我们返回了地址。多次调 --个结构体变量指针,因为Readdir内部申请了内存并且给我们返回了地址。多次调用readdir时,内部并不会重复申请内存,而是使用第一次调用readdir时分配的内存。这个设计方法是readdir不可重入的关键。
(3)readdir在多次调用时是有关联的,这个关联也表明readdir函数是不可重入的。
(4)库函数中有一些函数当年刚开始提供时都是不可重入的,后来意识到这种方式不安全,所以重新封装了c库,提供了对应的可重复版本(函数名一般包含_r)。