1. 程式人生 > >課下實踐——實現Mypwd

課下實踐——實現Mypwd

指向 clas 根目錄 學習 img error image stdio.h 一個

實現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);

}

測試代碼

技術分享圖片

課下實踐——實現Mypwd