pwd的实现
pwd命令
pwd命令以绝对路径的方式显示用户当前工作目录。命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用/分隔。第一个/表示根目录,最后一个目录是当前目录。执行pwd命令可立刻得知您目前所在的工作目录的绝对路径名称。
来自:
实现思路
从当前目录的目录名即“.”,首先使用opendir,readdir,closedir,读出当前目录的目录名。
DIR opendir(const char name);
struct dirent readdir(DIR dirp);
struct dirent { ino_t d_ino;//inode number off_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256];}
取的上级目录的i节点和当前目录的i节点比较,如果一样则说明已经到根节点,再回溯依次打印各级目录名。
遇到的问题
- 从struct dirent读出的i节点和从struct stat读出的i节点不一样。 用ls -i 命令验证后发现从stat里读出的节点号才是正确的。我又仔细查看了readdir的功能,发现目录文件虽然是文件,但是存储内容的只是一张表而已,关于文件名和inode号的映射关系。
The readdir() function returns a pointer to a dirent structure repre‐
senting ==the next directory entry== in the directory stream pointed to by dirp. It returns NULL on reaching the end of the directory stream or if ==an error occurred==.int stat(const char *pathname, struct stat *buf);
这也提示我,在打开关闭文件的时候,要判断是否打开关闭成功。
- 用“.”打开struct dirent读出的文件名不是当前目录名。
解决方法:通过stat读出正确的inode号,再用这个inode号读出正确的目录名。
- 取得的当前路径名是“.”
解决方法:调试发现,只有进入上级目录后,才能在读到下级目录的目录名。而在本级目录无法读出目录名。
最后成功运行,
代码
#include#include #include #include #include char *inode_to_name(int inode);void ppath();int main(int argc,char *argv[]){ ppath(); }char *inode_to_name(int inode) { char *str; DIR *dirp; struct dirent *dirt; if((dirp = opendir(".")) == NULL){ perror("."); exit(-1); } while((dirt = readdir(dirp)) != NULL) { if(dirt->d_ino == inode){ str = (char *)malloc(strlen(dirt->d_name)*sizeof(char)); strcpy(str,dirt->d_name); return str; } } perror("."); exit(-1); } void ppath(){ char* str; struct stat p,p1; if(stat(".",&p) == -1){ perror(str); exit(-1); } if(stat("..",&p1) == -1){ perror(str); exit(-1); } chdir(".."); str = inode_to_name(p.st_ino); if(p.st_ino == p1.st_ino) { return; } ppath(); printf("/%s",str);}