2. 文件权限及操作函数
(1)9种文件访问权限位
权限 |
权限常量(宏) |
用户权限 |
S_IRUSR、S_IWUSR和S_IXUSR |
组权限 |
S_IRGRP、S_IWGRP和S_IXGRP |
其它权限 |
S_IROTH、S_IWOTH和S_IXOTH |
备注 |
文件权限通过按位或的方式构造。如: int fd=open("test.txt", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH),相当于0644权限 |
【编程实验】显示文件权限
//file_perm.c
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <memory.h> /*查看给定文件的权限*/ //显示权限信息 void showPerm(mode_t mode) { //User permission if(S_IRUSR & mode){ printf("r"); }else{ printf("-"); } if(S_IWUSR & mode){ printf("w"); }else{ printf("-"); } if(S_IXUSR & mode){ printf("x"); }else{ printf("-"); } //Group permission if(S_IRGRP & mode){ printf("r"); }else{ printf("-"); } if(S_IRGRP & mode){ printf("w"); }else{ printf("-"); } if(S_IXGRP & mode){ printf("x"); }else{ printf("-"); } //Other permission if(S_IROTH & mode){ printf("r"); }else{ printf("-"); } if(S_IROTH & mode){ printf("w"); }else{ printf("-"); } if(S_IXOTH & mode){ printf("x"); }else{ printf("-"); } } int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stderr, "usage: %s files\n", argv[0]); exit(1); } struct stat buff; int i=0; for(i=1; i<argc; i++){ memset(&buff, 0, sizeof(buff)); if(lstat(argv[i], &buff) < 0 ) { perror("lstat error"); continue; } //获得文件的权限信息 mode_t mode = buff.st_mode; printf("%-20s", argv[i]); //显示权限信息 showPerm(mode); printf("\n"); } return 0; }
(2)accept函数
头文件 |
#include<unistd.h> |
函数 |
int access(const char* pathname, int mode); |
返回值 |
若成功则为0,若出错则为-1 |
功能 |
查看调用进程(所有者或所属组)是否可以对指定的文件执行某种操作 |
参数 |
(1)pathname:文件路径 (2)mode:文件的访问权限 ①R_OK:判断文件是否有读权限 ②W_OK:判断文件是否有写权限 ③X_OK:判断文件是否有可执行权限 ④F_OK:判断文件是否存在 |
备注 |
(1)Linux内核总是根据进程的有效用户ID和有效组ID来决定一个进程是否有权访问某个文件。但有时希望按实际用户ID和实际组ID 来测试其访问能力。 (2)access检查用户对一个文件的权限情况,根据mode的值检查调用进程对文件pathname是否具有读、写、或执行的权限。若进程实际用户具有mode所指出的权限,access返回0.否则返回-1 (3)Linux系统中某个可执行文件所有者为root并且有SetUID,当一个普通用户mike运行这个程序时,则产生的进程的有效用户为root,实际用户为mike。 |
【编程实验】判断当前进程对指定文件是否具有某种权限
//file_access.c
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> /*判断进程对某个文件是否具有指定的权限*/ int main(int argc, char* argv[]) { if (argc < 2){ fprintf(stderr, "usage: %s files\n", argv[0]); exit(1); } int i=0; for(i=1; i<argc; i++){ //判断指定文件是否存在 if(access(argv[i], F_OK)){ printf("%s is not exist\n", argv[i]); continue; } //判断当前进程(所有者或所属组)对指定文件是否具有读权限 if(access(argv[i], R_OK)){ printf("%d can not read %s\n", getpid(), argv[i]); }else{ printf("%d can read %s\n", getpid(), argv[i]); } //判断当前进程(所有者或所属组)对指定文件是否具有写权限 if(access(argv[i], W_OK)){ printf("%d can not write %s\n", getpid(), argv[i]); }else{ printf("%d can write %s\n", getpid(), argv[i]); } //判断当前进程(所有者或用户组)对指定文件是否具有执行权限 if(access(argv[i], X_OK)){ printf("%d can not execute %s\n", getpid(), argv[i]); }else{ printf("%d can execute %s\n", getpid(), argv[i]); } printf("\n"); } return 0; }
(3)umask函数
头文件 |
#include<sys/types.h> #include<sys/stat.h> |
函数 |
mode_t umask(mode_t mode); |
返回值 |
返回以前的设置的掩码。这个函数不会出错。 |
功能 |
指定在建立文件或目录时预设的权限掩码,并返回以前的值。 补充说明:umask可用来设定权限掩码。将要设定的文件权限减去权限掩码,即为新建文件的实际权限。 |
参数 |
mode:文件权限常量(如:S_IRGRP、S_IWGRP等) |
备注 |
(1)umask设置的权限掩码不能影响己创建的文件权限 (2)umask只影响当前进程新建文件的默认权限。并不影响其父进程(常常是shell)的掩码。 |
(4)chmod和fchmod函数
头文件 |
#include<sys/stat.h> |
函数 |
int chmod(const char* pathname, mode_t mode); int fchmod(int fd, mode_t mode); |
返回值 |
成功返回0,出错返回-1 |
功能 |
更改现存文件的权限。chmod函数在指定的文件上进行操作。而fchmod函数则对己打开的文件进行操作。 |
参数 |
(1)pathname:文件路径名字 (2)mode:文件权限(按位或操作) ①S_ISUID、S_ISGID和S_ISVTX //SetUID、SetGID和SetBID ②S_IRWXU、S_IRUSR、S_IWUSR和S_IXUSR ③S_IRWXG、S_IRGRP、S_IWGRP和S_IXGRP ④S_IRWXO、S_IROTH、S_IWOTH和S_IXOTH |
备注 |
更改一个文件的权限位,需要满足的条件: ①进程的有效用户ID必须等于文件的所有者ID(可用id命令查看当前用户ID及其组ID等信息) ②或者进程具有超级用户权限 |
【编程实验】更改文件权限
//file_chmod.c
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> /*更改指定文件的权限*/ #define MODE S_IRWXU | S_IRWXG | S_IRWXO #define UMASK S_IXUSR | S_IWGRP | S_IRWXO //0127 int main(int argc, char* argv[]) { if(argc < 2){ fprintf(stderr, "usage: %s file\n", argv[0]); exit(1); } //设置掩码 /* umask(UMASK); int fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, MODE); if (fd < 0){ perror("open error"); exit(1); } */ //更改文件的权限 int fd = open(argv[1], O_RDWR); if(fd < 0){ perror("open error"); exit(1); } fchmod(fd, MODE); //将己经存在的文件权限改为0777 close(fd); return 0; }
(4)文件截短函数:truncate和ftruncate函数
头文件 |
#include<sys/types.h> #include <unistd.h> |
函数 |
int truncate(const char* pathname, off_t length); int ftruncate(int fd, off_t length); |
返回值 |
成功返回0,出错返回-1 |
功能 |
文件截短 |
参数 |
(1)pathname:文件路径名字 (2)length:文件截短后的长度 |
备注 |
(1)在文件尾端处截去一些数据以缩短文件 (2)将一个文件的长度截短为0是一个特例,用O_TRUNC标志可以做到这一点。 (3)如果该文件以前的长度大于length,则超过length以外的数据就不再能存取。如果以前的长度短于length,则其后果与系统有关。 |
【编程实验】文件截短
//file_truncate.c
#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { if(argc < 3){ fprintf(stderr, "usage: %s file length\n", argv[0]); exit(1); } //判断进程对文件是否有写权限 if(access(argv[1], W_OK) < 0){ perror("write permission error"); exit(1); } //将文件截短为指定长度 if(truncate(argv[1], atoi(argv[2]))){ //atoi函数指字符串转为数字 perror("truncate error"); exit(1); } int fd = open(argv[1], O_RDONLY); if(fd < 0){ perror("open error"); exit(1); } //显示截短后的文件长度 long len = lseek(fd, 0L, SEEK_END); printf("file length: %ld\n", len); close(fd); return 0; }
原文:http://www.cnblogs.com/5iedu/p/6349821.html