Apue学习:Linux文件和目录

stat和 struct stat

struct stat
{
    mode_t st_mode;     //file type & mode
    ino_t st_ino;       //inode number
    nlink_t st_nlink:   //number of hard links
    uid_t st_uid;       //user ID of owner
    gid_t st_gid;       //group ID of owner
    struct timespec st_atime;    //time of last access
    struct timespec st_mtime;    //time of last modification
    struct timespec st_ctime;    //time of last file status change
    blkcnt_t st_blocks; //number of disk blocks allocated

    dev_t st_dev; //device number(file system)
    dev_t st_rdev: //device number for special files
};

st_mode中file type表示文件的属性,例如是否是目录,是否是普通文件的等等。
而mode包含文件的权限,如所有者权限,所属群组权限,其他人的权限。

struct timespec
{
  time_t tv_sec;   //秒
  long tv_nsec;    //纳秒
};
// 这个数据结构提供更高精度的时间tv_nsec

注意:
一定要记住,一个文件最重要的几条

  • 所有者,群组
  • inode number
  • 类型,权限
  • access time , modification time, change-status time

1)三个函数

#include <sys/stat.h>
int stat(const char *restrict pathname, 
         struct stat *restrict buf);

int fstat(int filedes, struct stat *buf);

int lstat(const char *restrict pathname, 
          struct stat *restrict buf);

注意lstat与stat的区别在于lstat可以读到链接文件的信息,而stat会读取链接文件链接到的文件的信息。

文件类型

1)文件类型及他们相关的测试宏,用法S_ISREG(mode),mode是st_mode类型。

1.普通文件:S_ISREG()

2.目录文件:S_ISDIR()

3.块特殊文件:S_ISCHR()

4.字符特殊文件:S_ISBLK()

5.FIFO:S_ISFIFO()

6.套接字:S_ISSOCK()

7.符号链接:S_ISLNK()

2)测试宏原理
例如:S_ISDIR()
#define S_ISDIR(mode) (((mode & S_IFMT) == S_IFDIR)

目录的访问顺序

例如对于 /usr/include/stdio.h的打开,首先我们要有/、/usr、/usr/include的执行权限,然后还要有对stdio.h文件的适当权限才可以打开。

新文件和目录的所有权

新文件的用户ID是进程的有效用户ID
新文件的组ID可以是进程的有效组ID,也可以是所在目录的组ID

当在一个进程中创建一个文件时,文件的user ID即所有者是这个进程的euid。而该文件的group ID,则有两种情况:
1.为这个进程的egid
2.这个文件必定创建在一个目录下,那么可以设置该文件的gID为这个目录的gID。这种作法必须设置目录的第六个权限为s,即该目录必须设置set gid。注意的是:这里指的是目录的群组gID,而不是目录的所有者。

access函数

用于判断当前进程的ruid是否有权限接触文件

int access(const char *pathname, int mode);

mode取值:
R_OK:read permission
W_OK:write permission
X_OK:execute permission

注意点:
需要注意的是如果二进制文件设置了set uid时,一个进程对于这个文件的access permission就有一点不同了。因为一个二进制文件设置了set uid,那么我们执行了这个文件之后,我们自己的euid就是这个文件的所有者的ID了。切记,切记。

unlink函数

说明:
unlink从目录中删除该项,并把文件的inode count减一

int unlink(const char *pathname);
/* 成功返回0,失败返回-1 */

注意点:
如果一个文件的inode的计数为0,这个文件就会被删除。
需要注意的是:如果在一个进程中打开了这个文件,这个文件就不会被删除。所以当一个文件被关闭了,内核会先去检查是否还有进程打开了这个文件,如果没有再去检查这个link count,此时如果为0,则文件被删除。

unlink的用法:一般用于临时文件
如果一个进程创建了一个文件,然后crash了,那么它创建的文件还会留着。但是如果用了unlink,即在创建一个文件之后马上unlink,这时虽然逻辑上删除了这个文件,但是这个文件依然是被这个进程打开的,除非这个进程调用close或者死亡了。这样这个进程依然可以处理这个文件。然后进程退出时,内核自动删除这个文件。
一般用于进程临时创建的文件,避免进程crash之后留下了许多临时文件。

rename函数

int rename(const char *oldname, const char *newname);

注意点:
对于oldname如果是一个普通文件,那么newname如果不存在就没事,如果存在那么就可以是目录,如果存在且不是目录,就会去删除newname
如果oldname是一个目录,那么newname不存在且不是oldname的后缀就没事,如果newname存在那么newname必须是一个空目录,执行rename时会删除这个目录。
如果oldname或newname是一个link文件,那么就会代表他们link的对象。
如果oldname == newname就没什么事发生,只是返回0

readlink函数

sszie_t readlink(const char *restrict pathname,
                 char *restrict buf,
                 size_t bufsize);

pathname指向一个符号链接文件,把这个符号链接中的内容读到buf中。成功返回读到的个数,失败返回-1。

file times

这里写图片描述
一个文件一般有3种时间:
access time
modify time:the time when the contents of the file were last modified
change status time:the time when the inode of the file were last modified

umask函数

#include <sys/stat.h>
mode_t umask(mode_t cmask);

九个访问权限:
这里写图片描述
cmask是这9个权限的位操作的结果。umask返回的是以前的屏蔽字。

注意点:
umask会设置当前的默认权限,并且返回以前的权限,对应文件中的9个权限。
需要注意的是,在没有umask时,即umask为0时:
普通文件的权限是666
目录文件的权限是777
有umask时,会再进行对应的减法操作,如umask=022,
那么创建一个普通文件:他的权限是666-022=644
创建一个目录文件:他的权限是777-022=755

读目录

#include <dirent.h>
DIR *opendir(const char *pathname);

struct dirent *readdir(DIR *dp);

void rewinddir(DIR *dp);
int closedir(DIR *dp);

说明:
1. DIR 类似于FILE。
2. readdir用于读取目录文件中的类容,执行过程类似于getline函数,readdir返回的是一个dirent类型。
3. rewinddir:把dp的偏移重新设置到目录文件的开始处。

struct dirent一般结构

struct dirent
{
    ino_t d_ino;               //inode number 
    char d_name[NAME_MAX + 1]; //null terminated filename
};

注意点:
d_name里面存的base name,即文件名,而不是绝对路径。

getcwd函数

获取当前绝对路径

char *getcwd(char *buf, size_t size);
成功返回buf,失败返回-1

注意buf必须足够大,还有字符\0也要存。

file access permission表格

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值