本文参考Unix linux编程实践教程,完成编写pwd命令,并介绍相关核心知识点。
命令pwd用来显示到达当前目录的路径。例如:
root@ubuntu:~/uup/experiments# pwd
/root/uup/experiments
root@ubuntu:~/uup/experiments#
pwd命令的实现思路:
1.得到当前目录.的i节点号
2.然后改变当前目录为父目录
3.与查询出来的目录信息通过i节点号比较
4.重复此过程
由于在根目录. 和..的i节点号相同,因此递归终止的条件是到达根目录。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <inttypes.h>
ino_t get_inode(char*);
void printpathto(ino_t);
void inum_to_name(ino_t,char*,int);
int main()
{
printpathto(get_inode(".")); //print path to here
putchar('\n');
return 0;
}
void printpathto(ino_t this_inode)
{
ino_t my_inode;
char its_name[BUFSIZ];
/*如果本目录的i-节点与上级目录不同,即本目录不是根目录root*/
if (get_inode("..") != this_inode)
{
chdir(".."); //进入上级目录
inum_to_name(this_inode,its_name,BUFSIZ);
my_inode = get_inode(".");
printpathto(my_inode);
printf("/%s",its_name);
}
}
void inum_to_name(ino_t inode_to_find,char* namebuf,int buflen)
{
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] = '\0';
closedir( dir_ptr);
return;
}
}
fprintf( stderr , "error looking for inum %ju\n" ,(uintmax_t)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;
}
可以通过使用gdb调试来理解上面的代码:
验证..和.只有在根目录才相同: