zoukankan      html  css  js  c++  java
  • 第4章 文件和目录(2)_文件权限及操作函数

    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
    ", 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("
    ");
        } 
        
        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
    ", argv[0]);
            exit(1);
        }
    
        int i=0;
        for(i=1; i<argc; i++){
            //判断指定文件是否存在
            if(access(argv[i], F_OK)){
                printf("%s is not exist
    ", argv[i]);
                continue;
            }
            
            //判断当前进程(所有者或所属组)对指定文件是否具有读权限
            if(access(argv[i], R_OK)){
                printf("%d can not read %s
    ", getpid(), argv[i]);
            }else{
                printf("%d can read %s
    ", getpid(), argv[i]);
            }
    
            //判断当前进程(所有者或所属组)对指定文件是否具有写权限
            if(access(argv[i], W_OK)){
                printf("%d can not write %s
    ", getpid(), argv[i]);
            }else{
                printf("%d can write %s
    ", getpid(), argv[i]);
            }
            
            //判断当前进程(所有者或用户组)对指定文件是否具有执行权限
            if(access(argv[i], X_OK)){
                printf("%d can not execute %s
    ", getpid(), argv[i]);
            }else{
                printf("%d can execute %s
    ", getpid(), argv[i]);
            }
    
            printf("
    ");
        }
    
        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
    ", 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
    ", 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
    ", len);
    
        close(fd);
    
        return 0;
    }
  • 相关阅读:
    ITIL 4Foundation认证
    Linux服务器安全之 fail2ban的安装与配置
    Linux的常用基础命令
    jQuery源码学习(2):选择器初窥
    jQuery源码学习(1):整体架构
    从字符串拼接看JS优化原则
    理解函数作用域与闭包
    JavaScript DOM节点操作总结
    函数声明与函数表达式、变量提升
    CSS长度单位详解
  • 原文地址:https://www.cnblogs.com/5iedu/p/6349821.html
Copyright © 2011-2022 走看看