实现mypwd
1.学习pwd命令
- pwd命令功能为输出当前所在工作目录的绝对路径名称
- 绝对路径和相对路径:
绝对路径:从根目录开始直到文件位置
相对路径:相对于程序当前所在目录到文件位置
绝对路径:home/wyf/grd_3/pwd
相对路径:./pwd
- 用
man pwd
命令查看pwd的详细功能
- pwd中有两个带参数的执行方式分别为
pwd -l
和pwd -p
pwd -l
功能为从环境中执行PWD命令,即使它包含符号链接pwd -p
功能为避免所有符号链接,执行pwd命令
- 分别执行两个命令,结果无区别,经查找发现是因为路径中无特殊符号链接
- 换了个目录尝试,发现了区别
2.研究pwd实现需要的系统调用(man -k; grep),写出伪代码
- 输入
man -k dir | grep 2
查看系统调用,可以发现getcwd函数,功能为获取当前工作目录
- 通过
man getcwd
命令查看getcwd函数功能
-
如图可知getcwd的功能是返回一个包含调用程序所在位置绝对路径的以空字符为结尾的字符串
-
char *getcwd(char *buf, size_t size);
函数的第一个参数为数组首地址,第二个参数为空间值,只要在程序中使用该函数就可以实现获得绝对路径的功能 -
只要在程序中使用调用char *getcwd(char *buf, size_t size)函数就可以实现获得绝对路径的功能,因此得到以下伪代码:
伪代码
调用char *getcwd(char *buf, size_t size)函数;
判断是否调用成功:
若失败,输出错误提示;
若成功,输出绝对路径,实现pwd功能;
3.利用inode-number实现mypwd
-
在一个文件系统中,一个inode代表一个文件,并使用一个整数值来表示该inode,称为inode-number,该值对于一个文件系统而言是唯一的,即通过该值可以找到其对应的inode。一般情况下,一个文件只有一个inode信息来描述它
-
因此,我们通常所说的目录a“包含”文件b,其实现层面上的意思是,目录a的内容列表里有一个关于文件b的列表项,即“b的inode-number+b的filename”。综上,Linux中,一个文件(包括目录)的文件名,及文件名与inode的对应关系,都是由包含该文件的目录所描述的
-
因此,我们可以利用inode-number实现pwd的功能
-
函数chdir()可帮助我们实现向上级目录的跳转
伪代码
获取初始目录名称
next:
获取当前目录的icode_number
通过chdir() 返回上一级目录
获得上一级目录的icode_number_ago
icode_number==icode_number_ago ?
不相等:
获取当前目录名称
返回next
相等
已经找到根目录,输出绝对路径
代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
ino_t get_inode(char*);
void print(ino_t);
void inum_to_name(ino_t,char*,int);
int main()
{
ino_t node=get_inode(".");
print(node); //打印当前目录绝对路径
putchar('
');
return 0;
}
void print(ino_t this_inode)
{
ino_t my_inode;
char its_name[BUFSIZ];
/*如果本目录的inode-number与上级目录不同,即本目录不是根目录*/
if (get_inode("..")!=this_inode)
{
chdir(".."); //进入上级目录
inum_to_name(this_inode,its_name,BUFSIZ);
my_inode = get_inode(".");
print(my_inode);
printf("/%s",its_name);
}
}
void inum_to_name(ino_t inode_to_find,char* namebuf,int buflen) //找到inode-number节点对应的文件名,并放在字符数组里
{
DIR* dir_ptr;
struct dirent* direntp;
dir_ptr = opendir(".");
if (dir_ptr == NULL)
{
perror(".");
exit(1);
}
while((direntp = readdir(dir_ptr)) != NULL)
{
if(direntp->d_ino == inode_to_find)
{
strncpy(namebuf,direntp->d_name,buflen);
namebuf[buflen-1] = '';
closedir( dir_ptr);
return;
}
}
fprintf( stderr , "error looking for inum % d
" ,inode_to_find);
exit (1) ;
}
ino_t get_inode(char* fname) //根据文件名,返回inode-number
{
struct stat info;
if ( stat( fname, &info) == -1){
fprintf( stderr , "Cannot stat ");
perror(fname);
exit (1);
}
return info.st_ino;
}