1. 程式人生 > >20165223 《資訊安全系統設計基礎》 實現mybash

20165223 《資訊安全系統設計基礎》 實現mybash

一、學習pwd命令

1. pwd命令簡介

  • 英文原名:Print Working Directory
  • 指令功能:打印出當前工作目錄
  • 執行許可權:All User
  • 指令所在路徑:/usr/bin/pwd 或 /bin/pwd

2. pwd命令基本語法

  • pwd [OPTION]

3. pwd命令引數

選項 描述
-L (即邏輯路徑logical ) 使用環境中的路徑,即使包含了符號連結
-P (即物理路徑physical) 避免所有的符號連結
–help 顯示幫助並退出
–version 輸出版本資訊並退出

4. pwd命令退出狀態

返回值 狀態
0 成功
非零值 失敗

二、研究pwd實現需要的系統呼叫(man -k; grep)並寫出虛擬碼

1. 實現pwd需要的系統呼叫

(1)先用man -k directory | gerp 2來檢視一下是否有可用命令

(2)發現命令getcwd符合找到當前目錄的要求

  • 使用man getcwd檢視系統呼叫

  • 找到需要的標頭檔案和函式引數
#include <unistd.h>

char *getcwd(char *buf, size_t size);

(3) 同時還需要用到chdir,來改變當前目錄

  • 使用man chdir檢視系統呼叫

  • 找到需要的標頭檔案和函式引數
#include <unistd.h>

int chdir(const char *path);

(4)命令readdir也符合要求,用於開啟並讀取當前目錄檔案

  • 使用man readdir檢視系統呼叫

  • 找到需要的標頭檔案和函式引數
#include <dirent.h>

struct dirent *readdir(DIR *dirp);

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

2. 虛擬碼

(1)用“.”獲取當前目錄的i-node(inode)
(2)用“..”獲取父級目錄的i-node(up_inode)
(3)判斷當前目錄的i-node和父級目錄的i-node是否相同
(4)相同:到達根目錄,輸出完整路徑,退出程式
(5)不同:還未到根目錄,切換至父級目錄,返回(1)再次執行相同操作直至兩個i-node相同

三、實現mypwd

#include<stdio.h>  
#include<sys/stat.h>  
#include<dirent.h>  
#include<stdlib.h>  
#include<string.h>  
#include<sys/types.h> 
#include <unistd.h> 
void printpath();  
char *inode_to_name(int);  
int getinode(char *);  
//功能:列印當前目錄路徑
void printpath()  
{  
    int inode,up_inode;  
    char *str;
    inode = getinode(".");  
    up_inode = getinode("..");  
    chdir("..");  
    str = inode_to_name(inode);  
    //噹噹前目錄的i-node與父級目錄的i-node相同時,到達根目錄
    if(inode == up_inode) {  
        return;  
    }  
    //列印路徑
    printpath();  
    printf("/%s",str);  
}  
//功能:獲取當前目錄的i-node
int getinode(char *str)  
{  
    struct stat st;  
    if(stat(str,&st) == -1){  
        perror(str);  
        exit(-1);  
    }  
    return st.st_ino;  
}  
//功能:獲取當前路徑
char *inode_to_name(int inode)  
{  
    char *str;  
    DIR *dirp;  
    struct dirent *dirt;  
    if((dirp = opendir(".")) == NULL){  
        perror(".");  
        exit(-1);  
    }  
    while((dirt = readdir(dirp)) != NULL)  
    {  
        if(dirt->d_ino == inode){  
            str = (char *)malloc(strlen(dirt->d_name)*sizeof(char));  
            strcpy(str,dirt->d_name);  
            return str;  
        }  
    }  
    perror(".");  
    exit(-1);  
}  
//主函式
int main()  
{  
    printpath();  
    putchar('\n');  
    return 0;  
}

四、測試mypwd

  • 測試截圖,成功

  • 用pwd命令檢測,一致