linux下pwd命令代码及注释

这是《Unix/Linux编程实践教程》上第四章的第一个例子,教给你怎样写一个最简单的pwd指令。pwd的功能是显示当前目录。这两章的内容很绕……全是目录、i节点、i节点表,读着读着就情不自禁的点着头唱起来了= =

效果图如下(和系统的完全一致哦~~):

还是先谈谈我的心得,代码附在文末:

1.一个目录都包含那些内容?

目录是什么?是一张表。其中的每一项都包含两个元素:inode号和文件名或者子文件夹名。子文件夹也是文件(又是另一张表)。文件的内容、属性保存在inode中,这张表包括了inode号,就能找到相应的inode内容,而他又保存了文件名,就把文件名与文件内容、属性联系起来了。这就是目录的作用。

2.如何获得当前文件夹名称?

用opendir(".")打开当前目录,通过readdir(dir_ptr)可以依次读取目录中的各项内容,其中就包括我们要的当前目录。

3.如何把当前目录筛选出来呢?

目录里的每一项内容都有相应的inode号,而通过stat(".",&infobuf)我们可以获得当前目录的inode号,这样,只要在一项一项readdir的时候,看看inode号是否一致,即可找出当前目录项目,从而输出其名称。

4.递归?

那么如何由根目录而外地输出目录名呢?即像显示的那样,先显示根目录,再依次显示。这就要用到递归,找到输出当前目录名称的程序语句,在其前一句调用函数本身。当然对于递归,要设置合适的出口,否则就死循环了……

代码及注释如下:

[c]

//spwd.c

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h>

//获得一个目录的inode号
//以便于配合readdir筛选
ino_t get_inode(char *);

//利用递归,由根目录向外
//依次显示各级目录
void printpathto(ino_t);

//在当前目录中
//根据inode号,寻找对应的
//文件或文件夹名称,保存在数组里
//注意:inode有对应类型ino_t,实际上还是个数。
void inum_to_name(ino_t ,char *,int);

int main()
{
//输入参数为当前目录
printpathto(get_inode("."));
putchar('n');
return 0;
}

void printpathto(ino_t this_inode)
{
ino_t my_inode;
char its_name[BUFSIZ];
//未到达根目录前都满足这个条件
if(get_inode("..") != this_inode)
{
//换到其上级目录
chdir("..");
//把上级目录的文件夹名存到its_name里
inum_to_name(this_inode,its_name,BUFSIZ);
//将当前目录(刚才切换的“上级目录”)
//的内容给my_inode
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);
}
//显示不停读取目录中的内容,if将每条内容加以判断
//判断inode号是否是我们需要的
//如果是,
while((direntp = readdir(dir_ptr)) != NULL)
if(direntp->d_ino == inode_to_find)
{
//将文件夹名复制到namebuf中,并添加'\0'
strncpy(namebuf, direntp->d_name,buflen);
namebuf[buflen-1] = '\0';
closedir(dir_ptr);
return;
}
//如果程序正常,在上面就return了
fprintf(stderr,"error looking for inum %dn",inode_to_find);
exit(1);
}

//怎么获得的?
//stat把文件名(目录文件)信息放到结构体
//返回结构体st_ino元素
//这里增加了一步出错处理
ino_t get_inode( char * fname)
{
struct stat info;
if(stat(fname,&info) == -1){
fprintf(stderr,"Cannot stat");
perror(fname);
exit(1);
}
return info.st_ino;
}
[/c]