• 文件和目录1(文件属性和权限)


    获取文件属性(struct stat):<sys/stat.h>
    int stat(const char* restrict pathname,struct stat* restrict buf);
    int fstat(int fd,struct stat* restrict buf);
    int lstat(const char* restrict pathname,struct stat* restrict buf); //获取软连接的文件属性
    struct stat{
      mode_t st_mode; //文件类型和访问权限
        ino_t st_ino; //inode编号
        dev_t st_dev; //设备号(对于文件系统来说)
        dev_t st_rdev; //设备号(对于特殊文件来说)
        nlink_t st_nlink; //链接数目
        uid_t st_uid; //文件所有者uid
        gid_t st_gid; //文件所有者gid
        off_t st_size; //文件大小
        time_t st_atime; //access time
        time_t st_mtime; //文件数据modification time    注意:acsess和stat函数不更改这三个时间
        time_t st_ctime; //属性最近一次change time
        blksize_t st_blksize; //block size
        blkcnt_t st_blocks; //blocks
    };
    <1>文件类型宏函数: 参数都是st_mode            <sys/stat.h>
    S_ISREG() //判断是否是普通文件  
    S_ISDIR() S_ISCHR()  S_ISBLK()  S_ISFIFO()  S_ISLNK()  
    S_ISSOCK()   //套接字
    <2>文件访问权限位和设置用户ID,设置组ID位都包含在st_mode中,st_mode屏蔽字如下(都是常量):
    //对文件的访问权限位
    S_IRUSR   S_IWUSR    S_IXUSR //用户读、写、执行
    S_IRGRP   S_IWGRP    S_IXGRP //组读、写、执行
    S_IROTH   S_IWOTH    S_IXOTH //其他读、写、执行
    S_IRWXU   S_IRWXG    S_IRWXO  //用户、组、其他可读写执行
    
    //与进程权限相关
    S_ISUID(设置uid位) S_ISGID(设置gid位) 
    S_ISVTX(粘贴位)
    
    
    文件访问权限说明

    <1>与每个进程相关的用户ID和组ID

    RUID RGID:(实际用户ID、实际组ID)标志我们(进程)是谁。在登录时取自口令文件中的登录项,只有超级用户进程可以改变
    EUID EGID:(有效用户ID、有效组ID、附属组ID)决定了我们(进程)文件访问权限。
    SUID SGID(保存的设置用户ID和保存的设置组ID):在执行一个程序时保存EUID EGID的副本。通过测试常量POSIX_SAVED_IDS  或 调用sysconf( _SC_SAVED_IDS做参数)判断系统是否支持这种特征。
    a,当执行一个程序文件时,通常EUID等于RUID,EGID等于RGID;
    b,但如果设置了设置用户ID位(S_ISUID)和设置组ID位(S_ISGID)时,当执行此文件时,EUID为文件的用户ID(st_uid),EGID为文件的组ID(st_gid)
    <2>某一进程对文件进行操作所需权限
    a,打开任意类型的文件(有可执行权限)
    b,删除文件(对包含该文件的目录有写和执行权限)
    c,在目录下创建文件(对该目录有写和执行权限)
    新文件的用户ID设置为进程的EUID;新文件的组ID可以是EGID 或者是它所在目录的组ID(当它所在目录的设置gid位被设置)

    测试访问权限

    文件访问权限测试(比如执行性权限):
    1.进程EUID是0,该进程是超级用户,可以对任意文件进行任何操作
    2.进程EUID等于文件的所有者ID(st_uid),且文件的用户可执行权限位为1。
    3.进程的EGID等于文件的所有组ID,且文件的组可执行权限位为1.
    4.文件的其他用户可执行权限位为1
    // <unistd.h>
    int access(const char *pathname, int mode)    
    //access是进程按照其RUID DGID来测试访问权限的,而open是按照EUID EGID
    //mode参数:R_OK     W_OK      X_OK     F_OK(文件是否存在)
    
    mode_t umask(mode_t cmask)
    //为进程设置文件模式创建屏蔽字,并返回以前的值。进程在创建新文件或目录时,cmask中为1的位在新文件mode中相应的位则被关闭
    //cmask参数:是个文件访问权限位按位或构成的或者是 0400(用户读)的形式

    更改现有文件访问权限

    // <sys/stat.h>
    int chmod (const char *pathname, mode_t mode);
    int fchmod(int filedes, mode_t mode);
    /*a,参数mode:是st_mode,先要用stat,fstat,lstat获取文件的struct stat
        mode一般是这种格式:statbud.st_mode & ~S_IXGRP | S_ISGID  设置文件的设置组ID位,取消文件的所有组可执行权限*/
    /*b,chmod在一定条件下自动清除两个权限位:
    如果是非超级用户试图设置粘住位,那么粘住位会被清除,只有root能设置普通文件的粘住位
    如果新创文件gid不等于进程egid或进程附加组id,并且是非超级用户,那么设置组ID位会被清除*/

    更改文件的uid和gid

    //<unistd.h>
    int chown (const char *pathname, uid_t owner, gid_t group);
    int lchown (const char *pathname, uid_t owner, gid_t group);
    int fchown (int filedes, uid_t owner, gid_t group);
    //参数:owner或group为-1或为文件的uid gid时,对应的uid gid不变
    /*若_POSIX_CHOWN_RESTRICTED对指定的文件起作用(定义在<unistd.h>可用pathconf/fpathconf函数查询):
    <1>只有root进程才允许更改uid.
    <2>非root进程改变gid的条件:euid等于文件uid(进程拥有此文件);或者文件uid不变,参数group等于进程euid或附加组ID之一*/
    //同时需要注意的是,如果这些函数由非超级用户调用,则在成功返回时,设置uid和gid位都会被清除

    文件截断

    文件长度:st_size(文件长度) 接近 st_blksize(文件使用块大小)和st_blocks(块数)的乘积。
    当文件有空洞时st_size可能很大,而实际占用磁盘空间较少
    文件截短:int truncate(const char* filename,off_t length);   int ftruncate(int fd,off_t length);   <unistd.h>
    如果length比原来文件短的话,那么文件在length偏移之后数据就不可以访问了。如果length比 原来文件长的话,那么会创造一个空洞出来
     

    符号链接

    //<unistd.h>
    int link(const char *exitingpath, const char *newpath)  //原子操作:创建一个新目录项(即链接) ,链接计数加1
    int unlink(const chat *pathname)   //删除一个目录项,链接计数减1
    a,解除对文件的链接的条件:对包含该目录项的目录有写和执行权限;若设置的粘住位,需满足以下条件之一:拥有该文件,拥有该目录,是root用户  
    b,文件链接数目为0时,文件就会被删除,因此,unlink可以删除文件;
            但当st_nlink=0时仍有进程访问该文件,那么磁盘空间不会被释放,该文件仍然可写。
    不跟随符号链接的函数(对链接本身起作用):
    函数不跟随链接跟随链接
    access
     
    Y
    chdir
     
    Y
    chmod
     
    Y
    chown
     
    Y
    creat
     
    Y
    exec
     
    Y
    lchown Y
     
    link
     
    Y
    lstat Y
     
    open
     
    Y
    opendir
     
    Y
    pathconf
     
    Y
    readlink Y
     
    remove Y
     
    rename Y
     
    stat
     
    Y
    truncate
     
    Y
    unlink Y
     
     
    symlink创建符号链接
    readlink打开符号链接并读该链接中的名字,open跟随符号链接
     
    更改文件的st_atime和st_mtime     <utime.h>
    int utime(const char *pathname, const struct utimebuf *times);
    参数times为空时,则两个时间设为当前时间
    struct utimebuf{
    time_t atime;
    time_t modtime;
    }
     
    目录操作
    int mkdir(const char *pathname, mode_t mode);          <sys/stat.h>
    读目录  <dirent.h>
    DIR *opendir(const char *pathname);
    struct dirent *readdir(DIR *dp);
    rewinddir  closedir  telldir  seekdir 
    更改当前的工作目录    <unistd.h>
    int chdir(const char *pathname);
    int fchdir(int fd);
    char *getcwd(char *buf, size_t size); // 获取当前动作目录 参数是缓冲区地址和长度
     
    特殊设备文件
    st_dev设备号   参数是st_dev : major()  minor()
    sr_rdev只有字符特殊文件和块特殊文件才有这个值,表示实际设备的设备编号。
  • 相关阅读:
    PHP设计模式之----简单工厂模式
    PHP设计模式之----单例模式
    php排序算法
    PHP代码实现二分法查找
    Centos 7 下安装PHP7.2(与Apache搭配的安装方式)
    PHPSTORM Live-Templates变量速查表
    Centos 7 设置ip地址
    Centos 7下编译安装Apache
    Centos 7下编译安装Mysql
    apache配置Directory目录权限的一些配置
  • 原文地址:https://www.cnblogs.com/zhoutian220/p/4020877.html
Copyright © 2020-2023  润新知