1. 程式人生 > >第9周 實現PWD命令

第9周 實現PWD命令

number 保存 ring exit include 參數 ref 函數 types

第9周 實現PWD命令

題目要求

  • 1 學習pwd命令
  • 2 研究pwd實現需要的系統調用(man -k; grep),寫出偽代碼
  • 3 實現mypwd
  • 4 測試mypwd

    學習pwd命令

  • 1:用man pwd 查看幫助文檔
    技術分享圖片

  • 2:顯示當前目錄所在路徑 pwd

    smile@ubuntu:~/dky5332$ pwd
    /home/smile/dky5332

  • 3:顯示當前目錄的物理路徑 pwd –P
  • 4: 顯示當前目錄的連接路徑:pwd -L

2.研究pwd實現需要的系統調用(man -k; grep),寫出偽代碼

man-k directory | grep 2
技術分享圖片

算法核心——偽代碼

  1. 拿到當前目錄中"."這個目錄的st_ino值,記為inode。
  2. 轉到父目錄中,遍歷父目錄,找到第一個st_ino值與inode相同的那個目錄,並保存名字。
  3. 再拿當前目錄中"."目錄的st_ino值作為inode,向前遞歸(此時的"."目錄已經不是1中的"."了,而是1中的"..")
  4. 輸出 “/" + 2中保存的名字

遞歸出口:

由於在根目錄下,"." 和 ".." 的inode值是一樣的,所以當遞歸到某一層,若父目錄的inode值與當前的inode值(作為遞歸函數的參數傳入) 相同,那麽就可以結束遞歸了。

3.實現pwd命令

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

測試pwd命令

技術分享圖片
技術分享圖片

第9周 實現PWD命令