pwd的实现
pwd命令
pwd命令以绝对路径的方式显示用户当前工作目录。命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用/分隔。第一个/表示根目录,最后一个目录是当前目录。执行pwd命令可立刻得知您目前所在的工作目录的绝对路径名称。
来自: http://man.linuxde.net/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 <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
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);
}