企业网站建设对网络营销的影响主要表现在( )/百度seo排名帝搜软件
此文着重介绍系统是如何表示目录的以及pwd命令的编写。
我们都知道Unix将磁盘分为三部分:超级块(superblock),节点表(inode table)以及数据区。超级块中记录文件系统本身的结构信息。节点表中记录文件的属性,文件系统中每个文件在表中都至少有一个i-节点,表中每个节点的大小相同。数据区就是文件数据真实的存储位置。
简要介绍磁盘知识后,我们来谈谈目录。在Unix中,目录是包含了文件名字列表的特殊文件,其抽象模型是一个包含i-节点号和文件名的表。所以一个目录的内容有两个部分:一个i-节点表和文件名表,其相互对应。对于文件来说,目录是找到该文件的一个索引(链接),本质上就是负责记录文件i-节点表与文件名的对应关系(一个文件可能对应好多个i-节点)。对于open、cat、cp等命令,都是通过在目录中寻找目的文件名,然后根据对应关系获取i-节点号以获取文件属性,最终获取文件内容来实现的。
假设目录demodir中有一个文件y,y文件对应的i-节点号是491。从系统角度来看,目录中有一个包含文件名y和i-节点号为491的入口,也可以说目录demodir中有一个指向i-节点号为491的链接,这个链接所附加的文件名为y。
说来说去这么绕,书上有一句结论概括地很好:目录包含的是文件的引用,每个引用被成为链接。文件的内容存储在数据块,文件的属性被记录在一个被称为i-节点的结构中,i-节点的编号和文件名存储在目录中。就像我前面说的,目录本质上是记录对应关系。
了解了pwd的内核属性后,我们来实现一下pwd。
此程序中使用递归语句实现,从当前目录不断循环深入直到”.”与”..”的i-节点号相同,即代表到达根目录,再由内向外打印出文件夹名。
逻辑不难理解,有一点需要注意,通过stat结构体我们可以获得”.”与”..”目录的i-节点号,我们需要通过节点号获取文件夹名。有点类似于一个trick,通过获得父目录的DIR结构体,取出父目录中包含当前目录在内的文件及文件夹的dirent结构体,通过比对结构体中d_ino字段与当前目录的inode,找到此inode所对应的的d_name即可。因此,程序中chdir必须在num_to_name之前。
/*pwd.c -print the directory where you in*/#include "stdio.h"
#include "string.h"
#include "dirent.h"
#include "sys/stat.h"
#include "unistd.h"
#include "stdlib.h"#define SIZE 100ino_t get_inode(char *path);
void print_path(ino_t cur_inode);
void num_to_name(ino_t inode, char *name);int main(int argc, char const *argv[])
{ino_t cur_inode;cur_inode = get_inode(".");print_path(cur_inode);printf("\n");return 0;
}
ino_t get_inode(char *path){struct stat info;if(stat(path, &info) == -1){perror("Get Inode");exit(1);}return info.st_ino;
}void print_path(ino_t cur_inode){char dname[SIZE];ino_t next_inode;if(cur_inode != get_inode("..")){chdir("..");num_to_name(cur_inode, dname); //必须放在chdir之后,要从父目录中找到innode和文件夹名的对应关系next_inode = get_inode(".");print_path(next_inode);printf("/%s", dname);}
}void num_to_name(ino_t inode, char *name){DIR *dir_ptr;struct dirent *direntp;dir_ptr = opendir(".");if(dir_ptr == NULL){perror("opendir");exit(1);}while((direntp = readdir(dir_ptr)) != NULL){if(direntp->d_ino == inode){strcpy(name, direntp->d_name);closedir(dir_ptr);return;}}perror("Can not fine with the innode");exit(1);
}