# 2017-2018-1 20155224 加分项-实现mypwd

2017-2018-1 20155224 加分项-实现mypwd

1. 学习pwd命令

  • pwd命令以绝对路径的方式显示用户当前工作目录。命令将当前目录的全路径名称(从根目录)写入标准输出。全部目录使用 / 分隔。第一个 / 表示根目录,最后一个目录是当前目录。执行pwd命令可立刻得知您目前所在的工作目录的绝对路径名称。

  • 命令格式:
    pwd [选项]

  • 命令功能:
    查看”当前工作目录“的完整路径

  • 常用参数:
    一般情况下不带任何参数
    如果目录是链接时:
    格式:pwd -P 显示出实际路径,而非使用连接(link)路径。

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

在linux 中的文件系统中,文件=N(N>=1)个inode +M(M>=1)个数据块。

数据块,存放文件的内容数据,数据块的数目根据文件内容的大小而定。

inode称为信息节点,其作用有二:1、存储跟文件相关的属性信息,如修改时间、所有者、文件类型和文件长度,注意这些信息里并没有文件名;2、存储指向文件内容数据块的指针信息。

在一个文件系统中,一个inode代表一个文件,并使用一个整数值来标志该inode,称为inode-number,该值对于一个文件系统而言是唯一的,即通过该值可以找到其对应的inode。一般情况下,一个文件只有一个inode信息用来描述它。

目录,在linux中,其实也是一种文件,所以它也是由“inode+数据块”构成的。而其文件内容是一个列表,每一个列表项记录“inode-number+filename",即文件名和i节点的对应关系表,而i节点才是记录此文件详细信息的结构,如文件大小,属性,权限,存在硬盘的那个块等。我们在一个目录创建文件就是在这张表里添加对应关系而已,使用某个文件时也是根据i节点确定在硬盘的实际存储位置的。

因此,我们通常所说的目录a"包含"文件b,其实现层面上的意思是,目录a的内容列表里有一个关于文件b的列表项,即“b的inode-number+ b的filename”。

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

综上,linux中,一个文件(包括目录)的文件名,及文件名与inode的对应关系,都是由包含该文件的目录所描述的。

3. 实现mypwd

#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("
");  
    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)] = '';  
            closedir(dir_ptr);  
            return ;  
        }  
    }  
    fprintf(stderr, "error looking for inode number %d
", (int)inode_num);  
    exit(1);  
}  

4. 测试mypwd

原文地址:https://www.cnblogs.com/nxy970408/p/7862839.html