zoukankan      html  css  js  c++  java
  • APUE(4)---文件和目录 (1)

    一、引言

      上一章执行I/O的基本函数(打开文件、读文件和写文件),本章将描述文件系统的其他特征和文件的性质,我们将从stat函数开始,并逐个说明stat结构的每一个成员以了解文件的所有属性。在此过程中,我们将说明修改这些属性的各个函数。

    二、函数stat、fstat、fstatat和lstat

    #include <sys/stat.h>
    int stat(const char *restrict pathname, struct stat *restrict buf);
    int fstat(int fd, struct stat *buf);
    int lstat(const char *restrict pathname, struct stat *restrict buf);
    int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);
    //若成功,返回0;若失败,返回-1

      若pathname给出绝对路径,则buf返回stat对应文件的信息;需要注意两点:lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息;fstatat当AT_SYMLINK_NOFOLLOW被设置时,不会跟随符号连接,而是同lstat一样,返回符号连接本身的有关信息,当AT_FDCWD被设置时,并且pathname是一个相对路径时,会从当前路径开始计算pathname。stat结构的基本形式如下:

    struct stat
    {
    mode_t                st_mode;
    ino_t                 st_ino;
    dev_t                 st_dev;
    dev_t                 st_rdev;
    nlink_t               st_nlink;
    uid_t                 st_uid;
    gid_t                 st_gid;
    off_t                 st_size;
    struct timespec       st_atime;
    struct timespec       st_mtime;
    struct timespec       st_ctime;
    blksize_t             st_blksize;
    blkcn_t               st_blocks;  
    };

    三、文件类型

      1.普通文件     :最常用的文件类型

      2.目录文件     :这种文件包含了其他文件的名字以及指向与这些文件有关信息的指针。

      3.块特殊文件  :每次访问以固定长度为单位

      4.字符特殊文件 :这种类型的文件提供对设备不带缓冲的访问。系统中的设备要么是字符特殊文件,要么是块特殊文件

      5.FIFO      :用于进程间通信,也称为命名管道

      6.套接字        :用于进程间网络通信

      7.符号连接      :这种类型的文件指向另一个文件

    #include "apue.h"
    
    int main(int argc, char *argv[])
    {
       int  i;
       char *ptr;
       struct stat buf;
    
       for(i = 1; i < argc; i++)
       {
           printf("%s:", argv[i]);
           if(lstat(argv[1], &buf) < 0)
           {
               err_ret("lstat error");
               continue;
           }
    
           if(S_ISREG(buf.st_mode))
           {
               ptr = "regular";
           }
           else if(S_ISDIR(buf.st_mode))
           {
               ptr = "directory";
           }
           else if(S_ISCHR(buf.st_mode))
           {
               ptr = "character special";
           }
           else if(S_ISBLK(buf.st_mode))
           {
               ptr = "block special";
           }
           else if(S_ISFIFO(buf.st_mode))
           {
               ptr = "fifo";
           }
           else if(S_ISLNK(buf.st_mode))
           {
               ptr = "symbolic link";
           }
           else if(S_ISSOCK(buf.st_mode))
           {
               ptr = "socket";
           }
           else
           {
               ptr = "unknown mode";
           }
           printf("%s
    ",ptr);
       }
    }

    4-3 对每个命令行参数打印文件类型

    四、设置用户ID和设置组ID

      与一个进程相关联的ID有6个或更多:实际用户ID和实际组ID:我们实际上是谁?有效用户ID和有效组ID和附属组ID:用于文件访问权限检查;保存的设置用户ID和保存的设置组ID:用于exec函数保存。

      每个文件有一个所有者和组所有者,由st_uid和st_gid指定。

    五、文件访问权限

      所有文件类型都有访问权限,很多人认为只有普通文件有访问权限,这是一种误解。一个文件的权限分为三部分:用户、组和其他,分别由读、写和执行组成。文件的权限有以下规则:

    1.我们用名字打开任一类型文件时,对改名字中包含的每一个目录,包括他可能隐含的当前工作目录都应具有执行权限,这也是为什么对于目录执行权限位常备称作搜索位的原因。对于目录而言:读权限意味获得在该目录中所有文件名的列表;执行权限意味进入该目录。

    2.为了在目录中创建一个新文件,我们必须具有该目录的写权限和执行权限

    3.为了删除目录中的一个文件,我们必须具有该目录的写权限和执行权限,而对于该具体文件而言,则不需要读、写权限。

    六、函数access和faccessat

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

    #include <unistd.h>
    int access(const char *pathname. int mode);
    int faccessat(int fd, const char *pathname. int mode);
    //成功返回0;失败返回-1
    #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
    ");
        }
    
        if(open(argv[1], O_RDONLY)<0)
        {
            err_ret("open error for %s", argv[1]);
        }
        else
        {
            printf("open for reading %s
    ", argv[1]);
        }
        exit(0);
    }

    4-8 access函数实例

  • 相关阅读:
    1015. 德才论
    1014. 福尔摩斯的约会
    1013. 数素数
    1012. 数字分类
    1011. A+B和C
    1010. 一元多项式求导
    1009. 说反话
    1008. 数组元素循环右移问题
    1007. 素数对猜想
    1006. 换个格式输出整数
  • 原文地址:https://www.cnblogs.com/cauchy007/p/5608945.html
Copyright © 2011-2022 走看看