stat结构体
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; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //伟建内容对应的块数量
};
4.3 文件类型
由 st_mode字段来决定
1.普通(regular)文件 S_ISREG()
2.目录文件 S_ISDIR()
3.快特殊文件 S_ISBLK() 跟设备有关,访问以固定长度为单位进行
4.字符特殊文件 S_ISCHR() 也跟设备有关,但是访问长度可变
系统中的所有设备,要么是字符特殊文件,要么是块特殊文件
5.FIFO S_ISFIFO()用于进程间通信,别称 命名管道(named pipe)
6.socket S_ISSOCK()用于进程间网络通信
7.符号链接 S_ISLNK()用来指向另一个文件
找到apue的filetype.c文件,gcc编译以后运行,可得到如下结果:
lstat会显示symbolic link,而stat函数是不会的
4.4 设置用户ID和设置组ID
st_mode中有两位,叫设置用户ID和设置组ID位(S_ISUID, S_ISGID),这两位置1,表示 当前进程的权限为此文件所有者的用户ID, 例如passwd 就是如此,无论哪个用户执行passwd,最终的权限都是变成root权限,
因为passwd是root所有, 一句话 谁执行passwd,都拥有root权限
4.5 文件访问权限
也由st_mode指定
每个文件有9个访问权限,文件包含上述所提到的所有7种类型
chmod用来修改文件权限,因为有9位,所以chmod 777 就代表9个权限(9个1)都开启
看不下去了,。。。看到89页 第一个规则是
4.7 access函数
92页这里,为啥最后open ok,我没看懂
4.8 umask函数
用来屏蔽 读、写、执行(rwx)的权限的,比如下面 0022 就对应 组权限rx,其他用户权限rx
root@ubun2004:/home/learnApue/apue.3e/filedir# umask
0022
root@ubun2004:/home/learnApue/apue.3e/filedir# umask -S // 读写模式显示
u=rwx,g=rx,o=rx
root@ubun2004:/home/learnApue/apue.3e/filedir# umask 027 //手动设置mask屏蔽位
root@ubun2004:/home/learnApue/apue.3e/filedir# umask -S
u=rwx,g=rx,o=
root@ubun2004:/home/learnApue/apue.3e/filedir#
4.9 函数chmod
改变文件权限
运行命令,结果如下:
root@ubun2004:/home/learnApue/apue.3e/filedir# gcc changemod.c
root@ubun2004:/home/learnApue/apue.3e/filedir# ls -l foo bar
-rw------- 1 root root 0 Sep 4 07:09 bar
-rw-rw-rw- 1 root root 0 Sep 4 07:09 foo
root@ubun2004:/home/learnApue/apue.3e/filedir# changemod
changemod: command not found
root@ubun2004:/home/learnApue/apue.3e/filedir# ./a.out
root@ubun2004:/home/learnApue/apue.3e/filedir# ls -l foo bar
-rw-r--r-- 1 root root 0 Sep 4 07:09 bar
-rw-rwSrw- 1 root root 0 Sep 4 07:09 foo
4.11 函数chown
用来改变文件的用户ID和组ID
4.12 文件长度
st_size字段,普通文件长度可能是0,目录长度一般是(16或者512的整数倍)
4.13 文件截断
trunctate和ftrunctate,trunctate用来截断文件,ftrunctate用来产生文件空洞
4.14 文件系统
磁盘分区和文件系统的关系:
柱面组的i节点和数据块
上图中有个i节点被多个目录块指向,称之为链接,链接的个数,在stat里面以st_nlink表示
nlink_t st_nlink; //文件的连接数
我们使用mv移动文件时,其实没有移动实际内容,只要构造一个新的目录块,指向现有i节点,然后删除老的目录块即可
目录文件的i节点,链接数至少为2,因为有.和..这两个目录节点指向它
看到103页
4.15 函数link
将目录块的目录项指向i节点的过程,称为link
要删除目录项,则使用unlink函数,当某个文件的链接数为0,该文件的内容才可被删除,不过通常用rmdir删除目录项
df: 查看当前磁盘空间情况
root@ubun2004:/home/learnApue/apue.3e/filedir# df .
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda6 9776636 3080220 6180064 34% /home
root@ubun2004:/home/learnApue/apue.3e/filedir# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 491981 466 491515 1% /dev
tmpfs 499385 970 498415 1% /run
/dev/sda7 5619712 215128 5404584 4% /
tmpfs 499385 1 499384 1% /dev/shm
tmpfs 499385 4 499381 1% /run/lock
tmpfs 499385 18 499367 1% /sys/fs/cgroup
/dev/loop0 10803 10803 0 100% /snap/core18/2074
/dev/loop3 18500 18500 0 100% /snap/gnome-3-34-1804/72
/dev/loop2 10803 10803 0 100% /snap/core18/2128
/dev/loop4 62342 62342 0 100% /snap/gtk-common-themes/1506
/dev/loop1 25913 25913 0 100% /snap/gnome-3-34-1804/24
/dev/loop5 474 474 0 100% /snap/snapd/12704
/dev/loop6 64986 64986 0 100% /snap/gtk-common-themes/1515
/dev/loop7 15841 15841 0 100% /snap/snap-store/547
/dev/loop8 15827 15827 0 100% /snap/snap-store/433
/dev/loop9 474 474 0 100% /snap/snapd/12883
/dev/sda1 62464 319 62145 1% /boot
/dev/sda6 625856 193503 432353 31% /home
tmpfs 499385 100 499285 1% /run/user/1000
4.16 函数rename
重命名,但是不能对 .和 .. 重命名,其他没啥内容
4.17 符号链接
ln命令: 创建一个符号链接,lrwxrw中的l代表文件类型,他是一个符号链接
root@ubun2004:/home/learnApue/apue.3e# mkdir foo
root@ubun2004:/home/learnApue/apue.3e# touch foo/a
root@ubun2004:/home/learnApue/apue.3e# ln -s ../foo foo/testdir
root@ubun2004:/home/learnApue/apue.3e# ls -l foo
total 0
-rw-r--r-- 1 root root 0 Sep 12 04:41 a
lrwxrwxrwx 1 root root 6 Sep 12 04:42 testdir -> ../foo
上述命令建立的链接关系如下图:
4.18 创建和读取符号链接
symlink创建
readlink读取
4.19 文件的时间
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
修改和状态更改的区别,修改是文件内容被修改,状态更改是文件的i节点最后一次被修改的时间
4.20 futimens,utimensat
修改文件的访问和修改时间,times[2]分别指定
4.21 mkdir和rmdir
创建和删除目录
4.22 文件目录
看不下去
4.23 函数chdir、fchdir和getcwd
chidir就是cd
当前工作目录是进程的一个属性
getcwd就是一个函数,向上递归获取目录值,最终能获取绝对路径名
4.24 设备特殊文件
stat结构体重,st_dev 为设备号所用的数据类型,只有字符特殊文件和块特殊文件有st_rdev值,st_rdev代表实际设备号
#include "apue.h"
#ifdef SOLARIS
#include <sys/mkdev.h>
#endif
int
main(int argc, char *argv[])
{
int i;
struct stat buf;
for (i = 1; i < argc; i++) {
printf("%s: ", argv[i]);
if (stat(argv[i], &buf) < 0) {
err_ret("stat error");
continue;
}
printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));
if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)) {
printf(" (%s) rdev = %d/%d",
(S_ISCHR(buf.st_mode)) ? "character" : "block",
major(buf.st_rdev), minor(buf.st_rdev));
}
printf("\n");
}
exit(0);
}
输出结果如下:
8/3 代表主设备号是8,从设备号是3
(character) rdev代表子设备或者块设备的号码(S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode))