UNIX环境高级编程-第4章- 文件和目录 - 一

4.2 stat,lstat 和fstat函数

/*********************** 
 * 函数功能: 描述文件属性
 * stat函数返回与pathname命名文件的相关信息结构; 
 * fstat函数获取已在描述符filedes上打开的文件信息; 
 * lstat函数获取符号连接的相关信息; 
 * 
 * 返回值:若成功则返回0,若出错则返回-1; 
 * 函数原型: 
 */  
  
int stat(const char *pathname, struct stat *buf);  
int fstat(int filedes, struct stat *buf);  
int lstat(const char *pathname, struct stat *buf);  
  
/************************** 
 * 参数说明 
 * pathname 文件名 
 * filed    文件描述符 
 * buf      指向buffer的指针 
 * */  

//buf指针指向的struct stat的结构
struct stat{  
    mode_t      st_mode;    /* file type */  
    ino_t       st_ino;     /* i-node number */  
    dev_t       st_dev;     /* device number */  
    dev_t       st_rdev;    /* device number for special file */  
    nlink_t     st_nlink;   /* number of hard link */  
    uid_t       st_uid;     /* user ID of owner */  
    gid_t       st_gid;     /* group Id of owner */  
    off_t       st_size;    /* total size in bytes for regular files */  
    blksize_t   st_blksize; /* blocksize for filesystem I/O */  
    blkcnt_t    st_blocks;  /* number of blocks allocated */  
    time_t      st_atime;   /* time of last access */  
    time_t      st_mtime;   /* time of last modification */  
    time_t      st_ctime;   /* time of last change */  
};  
 
测试程序:
#include "apue.h"  
#include <unistd.h>  
#include <fcntl.h>  
#include <sys/stat.h>  
  
void stat_buf(char*,struct stat *);  
  
int main(int argc, char *argv[])  
{  
    struct stat buf;  
  
    if(argc != 2)  
        err_quit("usage: a.out <pathname>");  
    if(stat(argv[1],&buf) != -1)  
    {  
        stat_buf(argv[1],&buf);  
    }  
    else  
        err_ret("error");  
    exit(0);  
}  
  
void stat_buf(char *fname,struct stat *buf)  
{  
    printf("mode: %o\n", buf->st_mode);     /*显示文件模式字段*/  
    printf("links:%d\n", buf->st_nlink);    /*显示链接数*/  
    printf("user : %d\n", buf->st_uid);     /*显示用户名ID*/  
    printf("group : %d\n", buf->st_gid);    /*显示组ID*/  
    printf("size: %d\n", buf->st_size);     /*显示文件大小*/  
    printf("modtime: %d\n", buf->st_mtime); /*显示文件的最后修改时间*/  
    printf("name:%s\n", fname);             /*显示文件名*/  
}  

4.3 文件类型

st_mode文件类型有以下七种:



st_mode文件类型宏:
/* 
 * S_ISREG      普通文件; 
 * S_ISBLK      块特殊文件; 
 * S_ISCHR      字符特殊文件; 
 * S_ISDIR      目录文件; 
 * S_ISLNK      符号链接; 
 * S_ISFIFO     命令管道; 
 * S_ISSOCK     套接字; 
 */  
//测试程序,取命令行参数,针对每个命令行参数打印其文件类型,代码如下:
#include "apue.h"  
    
int main(int argc, char*argv[])  
{  
    int i;  
    struct stat buf;  
    char *ptr;  
  
    for(i=1;i<argc;i++)  
    {  
        printf("%s: ",argv[i]);  
        if(lstat(argv[i],&buf) < 0)  //使用lstat函数可以坚持符号链接
        {  
            err_ret("last error.");  
            continue;  
        }  
        if(S_ISREG(buf.st_mode))  
            ptr = "regular file.";  
        else if(S_ISDIR(buf.st_mode))  
            ptr = "directory file.";  
        else if(S_ISCHR(buf.st_mode))  
            ptr = "character special file";  
        else if(S_ISBLK(buf.st_mode))  
            ptr = "block special  file";  
        else if(S_ISFIFO(buf.st_mode))  
            ptr = "FIFO file";  
        else if(S_ISLNK(buf.st_mode))  
            ptr = "symbolic link file";  
        else if(S_ISSOCK(buf.st_mode))  
            ptr = "sock file";  
        else  
            ptr ="** unknown mode **";  
        printf("%s\n",ptr);  
  
    }  
    exit(0);  
}  


4.4 设置用户ID(UID)和设置组ID(GID)

与一个进程相关联的ID有6个或更多,它们如下:


通常,有效用户ID等于实际用户ID,有效组ID等于实际组ID。但是,可以在文件模式字(st_mode)中设置一个特殊标志,其含义是“当执行此文件时,将进程的有效用户ID设置为文件所有者的UID。”对于有效组ID也可以设置。

4.5 文件访问权限

文件访问权限,

/***************************** 
 * 文件访问权限 
 * st_mode屏蔽    意义 
 * S_IRUSR      用户-读 
 * S_IWUSR       用户-写 
 * S_IXUSR       用户-执行 
 ***************************** 
 * S_IRGRP       组-读 
 * S_IWGRP       组-写 
 * S_IXGRP       组-执行 
 ***************************** 
 * S_IROTH       其他-读 
 * S_IWOTH       其他-写 
 * S_IXOTH       其他-执行 
 ***************************** 
 */  

对于目录的读权限:允许读目录,即获得该目录下所有文件名的列表。

对于目录的写权限:允许对目录进行增删文件。

对于目录的执行权限:允许进入目录。当一个目录是我们要访问的文件的路径名的一个组成部分时,需要该目录有可执行权限。

当一个进程每次打开,创建或者删除一个文件时,内核需要进行文件访问权限测试,这种测试可能涉及到文件的UID和GID,进程的有效ID和附加组ID。具体测试过程如下:

 

4.6 新文件与目录的所有权

 

/***************************** 
 * 新文件和目录的所有权 
 * 新文件的用户ID设置为进程的有效用户ID; 
 * 新文件的组ID为以下之一: 
 * (1)可以是进程的有效组ID; 
 * (2)可以是所在目录的组ID; 
 * *************************** 
 */  

4.7 access函数

         当用open函数打开一个文件时,内核以进程的有效用户ID和有效组ID为基础执行其访问权限测试。有时,进程希望按其实际用户ID和实际组ID来测试其访问能力。access函数就是按实际用户ID和实际组ID进行访问权限测试的。

/* access 函数 */  
/****************** 
 *功能:按照实际用户ID和实际组ID进行访问权限测试。 
 * 返回值:若成功则返回0,若出错则返回-1; 
 * 函数原型: 
 * int access(const char *pathname,int mode); 
**********************/  
/********************** 
 *参数说明 
 *pathname是文件名 
 *mode是一下常量 
 *(1)R_OK   测试读权限 
 *(2)W_OK   测试写权限 
 *(3)X_OK   测试执行权限 
 *(4)F_OK   测试文件是否存在 
 * *********************/  
  
#include "apue.h"  
#include <fcntl.h>  
  
int main(int argc, char*argv[])  
{  
    if(argc != 2)  
        err_quit("usage: a.out <pathname>");  
    if(access(argv[1],R_OK) < 0)  
        err_ret("access error for %s",argv[1]);  
    else  
        printf("read access ok.\n");  
    if(open(argv[1],O_RDONLY) < 0)  
        err_ret("open error for %s",argv[1]);  
    else  
        printf("open for reading ok.\n");  
    exit(0);  
}  


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值