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);
}