课下实践——实现Mypwd

实现Mypwd

学习pwd命令

  • 想要知道当前所处的目录,可以用pwd命令,该命令显示整个路径名。
  • L 目录连接链接时,输出连接路径
  • P 输出物理路径

研究pwd实现需要的系统调用(man -k; grep),写出伪代码

  • 内核为每个目录都设置了一个指向自己的i节点入口,即".",还有一个指向其父目录i节点的入口,即”..",我们首先获取当前目录的i节点编号,但是并不能知道当前目录的名称,我们切换到其的父目录,在里面寻找当前i节点编号对应的文件名即可。这样我们就很容易联想到使用递归来实现,但是终止条件是什么呢?在Unix文件系统的根目录中,“."和“..”指向同一个i节点,我们可以以此判断是否发到达了根目录,
  • 伪代码:
int main(){
    if("."".."不指向同一个节点。){    
    递归调用(切换到父目录
    寻找当前节点对应文件名)
}
}

实现

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

#define SIZE 128

ino_t get_inode(char *dirname);
void get_work_dir(ino_t inode_num);
void inode_to_dirname(ino_t inode_num, char *buf, int buflen);

int main(void)
{
    get_work_dir(get_inode("."));   
    printf("\n");
    return 0;

}

ino_t get_inode(char *dirname)
{
    struct stat info;
    if (stat(dirname, &info) == -1)
    {
        perror("dirname");
        exit(1);
    }

    return info.st_ino;
}

void get_work_dir(ino_t inode_num)
{
    ino_t parent_inode;
    char buf[SIZE];
    if (get_inode("..") != inode_num)
    {
        chdir("..");
        inode_to_dirname(inode_num, buf, SIZE);
        parent_inode = get_inode(".");
        get_work_dir(parent_inode);
        printf("/%s", buf);
    }
}

void inode_to_dirname(ino_t inode_num, char *buf,int buflen)
{
    DIR *dir_ptr;
    struct dirent *dire;
    if ((dir_ptr = opendir(".")) == NULL)
    {
        perror(".");
        exit(1);
    }

    while ((dire = readdir(dir_ptr)) != NULL)
    {
        if (dire->d_ino == inode_num)
        {
            strncpy(buf, dire->d_name, buflen);
            buf[strlen(buf)] = '\0';
            closedir(dir_ptr);
            return ;
        }
    }
    fprintf(stderr, "error looking for inode number %d\n", (int)inode_num);
    exit(1);

}

测试代码

posted @ 2017-11-18 20:42  20155204王昊  阅读(172)  评论(0编辑  收藏  举报