4、 文件和目录

1、stat返回与文件相关的结构信息

#include <sys/stat.h>
//restrict 告诉编译器,对象被指针引用,不允许通过其他方式修改
int stat(const char *restrict pathname, struct stat *restrict buf);

int fstat(int fd, struct stat *restrict buf);

//lstat类似stat,但是当命名文件是一个符号链接时,它获得符号链接的信息
int lstat(const char *restrict pathname, struct stat *restrict buf);

//fstatat可以针对相对路径
int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf);

//结构struct stat
struct stat{
            mode_t st_mode;    //文件类型和权限
            ino_t st_ino;
            dev_t st_dev;
            dev_t st_rdev;
            nink_t st_nlink;
            uid_t st_uid;      //用户id
            gid_t st_gid;      //用户组id
            off_t st_size;     //大小以字节为单位
            struct timespec st_atime;
            struct timespec st_mtime;
            struct timespec st_ctime;
}

2、文件类型
(1)普通文件
(2)目录文件:包含其他文件名字及指向这些文件有关信息的指针
(3)块文件
(4)字符文件
(5)FIFO:命名管道,用于进程间通信
(6)socket:用于进程间网络通信
(7)符号链接

3、与进程相关的ID,实际用户ID是文件的性质,有效ID是进程的性质
(1)实际用户ID:登录时对应口令文件中的ID
(2)有效用户ID:当前执行进程所属的用户ID,用于文件访问权限检查
(3)保存的设置用户ID:如果一个程序是设置用户ID程序,运行时可以得到额外的权限。

    文件访问权限:用户(所有者)、组、其他人分别有对应的读、写、执行权限
(1)进入目录要有执行权限,读权限允许获得目录中文件列表
(2)删除一个文件需要对其目录有写和执行权限,对文件本身不需要

    内核测试过程,先判断属于哪类人,再判断权限
(1)有效用户ID是0(root),允许访问
(2)进程的有效用户ID等于文件所有者ID?
(3)进程有效组ID等于文件组ID?
(4)其他人

    新文件和目录的所有权,新文件的用户ID等于进程有效用户ID。Linux中可以选择新文件的用户组ID等于进程组ID或目录组ID。

4、access访问权限测试

//mode 可以为F_OK测试文件是否存在,或者测试权限R_OK,W_OK,X_OK
int access(const char *pathname, int mode);

//如果flag等于AT_EACCESS,访问检测用的是调用进程的有效用户ID和有效组ID 
int faccessat(int fd, const char *pathname, int mode, int flag);

5、umask,控制创建文件的默认权限,拒绝置1的权限

//返回之前创建的屏蔽字
mode_t umask(mode_t cmask);

$umask 
0022

$umask -S
u=rwx,g=rx,o=rx

6、chmod修改权限

//改变一个文件权限位时,进程有效用户ID必须等于文件所有者ID
int chmod(const char *pathname, mode_t mode);

//对已打开的文件操作
int fchmod(int fd, mode_t mode);

int fchmodat(int fd, const char *pathname, mode_t mode, int flag);

7、chmod,当_POSIX_CHOWN_RESTRICTED有效时,可以更改你所在文件组的文件ID,但只能更改到你所属的组。

int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int fchownat(int fd, const char *pathname, uid_t owner, gid_t group, int flag);
int lchown(const char *pathname, uid_t owner, gid_t group);

8、truncate截断

//按长度length截断文件
int truncate(const char *pathname, off_t length);
int ftruncate(int fd, off_t length);

9、文件系统
文件是文件系统对数据的分割单元。文件系统用目录来组织文件,赋予文件以上下分级的结构。在硬盘上实现这一分级结构的关键,是使用 inode 来虚拟普通文件和目录文件对象。在Linux系统中,目录也是一种文件。所以/home/sammy 是指向目录文件 sammy 的绝对路径。

一个文件可以分成几个数据块存储在分区内。为了搜集各数据块,我们需要该文件对应的inode。每个文件对应一个 inode。这个 inode 中包含多个指针,指向属于该文件各个数据块。当操作系统需要读取文件时,只需要找到对应 inode,收集分散的数据块,就可以收获我们的文件了。

这里写图片描述
10、 link、linkat、unlink、unlinkat

//创建一个指向现有文件的链接,链接是指向i节点的链接
int link(const char *existingpath, const char *newpath);
int linkat(int efd, const char *existingpath, int nfd, const char *newpath, int flag);

//删除一个文件指向i节点的链接,当所有指向i节点的链接都删除才会释放i节点指向的空间
int unlink(const char *pathname);
int unlinkat(int fd, const char *pathname, int nfd, int flag);


//unlink后查不到创建的文件,但是文件是打开的,内容不会删除。当进程终止时内核会关闭进程打开的所有文,这时文件内容才会被删除。
#include "apue.h"
#include <fcntl.h>

int main()
{
    if(open("tempfile", O_RDWR) < 0)
        err_sys("open error");

    if(unlink("tempfile") < 0)
        err_sys("unlink error");

    printf("file unlink\n");

    sleep(15);

    printf("done \n");

    exit(0);

}

11、rename重命名

int rename(const char *oldname, const char *newname);
int renameat(int oldfd, const char *oldname, int newfd, const char *newname);

12、符号链接
这里写图片描述
硬链接: 与普通文件没什么不同,inode 都指向同一个文件在硬盘中的区块
软链接: 保存了其代表的文件的绝对路径,是另外一种文件,在硬盘上有独立的区块,访问时替换自身路径。此链接文件也是一个文件,它指向file

//创建符号链接
int symlink(const char *actualpath, const char *sympath);
int symlinkat(const char *actualpath, int fd, const char *sympath);

//open会打开符号链接指向的对象
//readlink读符号链接本身,合成open、read、close一体
ssize_t readlink(const char *restrict pathname,  char *restrict buf, size_t bufsize);
ssize_t readlinkat(int fd, const char *restrict pathname,  char *restrict buf, size_t bufsize);

13、文件时间

//每次文件被修改后会自动调用下面函数修改对应时间
st_atim //文件数据的最后访问时间
st_mtim //文件数据的最后修改时间
st_ctim //i节点状态的最后修改时间

//times[0]为访问时间,times[0]为修改时间
int futimens(int fd, const struct timespec times[2]);
int ufutimensat(int fd, const char *path, const struct timespec times[2], int flag);

14、目录相关函数,目录也是一种文件

int mkdir(const char *pathname, mode_t mode);
int mkdir(int fd, const char *pathname, mode_t mode);

//当目录为空才可以调用这个函数
int rmdir(const char *pathname);

//只有内核才能写目录(目录文件的内容),所谓目录的读写权限是能否在目录下新建或删除文件,他们不是写目录本身
DIR *opendir(const char *pathname);
DIR *fopendir(int fd);

struct dirent *readdir(DIR *dp);

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

long telldir(DIR *dp);
void seekdir(DIR *dp, long loc);

15、chdir 改变当前工作目录
    每个进程都有一个当前工作目录,此目录是搜索所有相对路径的起点。当前工作路径是进程的属性,起始目录是登录名的属性。
    每个程序运行在独自的进程中。要改变shell进程的自己工作目录,shell应该直接调用chdir函数,cd命令内建在shell中。

int chdir(const char *pathname);
int fchdir(int fd);

//返回完整的绝对目录
//成功返回buf,buf为缓冲区,size为缓存区长度
char *getcwd(char *buf, size_t size);

15、设备特殊文件
    主设备号标志设备驱动文件,此设备号标志特定的子设备。同一磁盘驱动器上的各文件系统具有相同的主设备号,但是次设备号不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值