zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155201 《信息安全系统设计基础》 pwd命令的实现

    2017-2018-1 20155201 《信息安全系统设计基础》 pwd命令的实现

    一、对pwd命令的学习

    在终端中输入man pwd查看手册中对pwd这一命令的解释:

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

    偷懒版:
    man pwd中可以发现一个c语言库中一个名为getcwd函数,man getcwd查看详细解释:

    于是写一个简单的测试代码,果然跟pwd实现的功能一样

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main(){
    	char *filepath=NULL;
    	filepath=getcwd(NULL,0);
    	puts(filepath);
    	free(filepath);
    	return 0;
    }
    

    但这太偷懒了,以下结合i-Node完成pwd命令功能的实现。

    二、实现pwd功能的伪代码

    通过上课了解到,文件与i节点其实是连在一起的,在命令行中我们经常使用cd ..命令返回上级目录,每个目录其实都是与i节点连在一起的,通过ls -i -a可以查看...目录对应的i节点值。

    我们发现,目录的上级目录..对应的i-Node和上级目录的当前目录.的i-Node一致,证明文件路径通过i-Node连接。所以想要完成pwd功能,必须找到一个能查询目录i-Node的函数。
    stat结构体:

    struct stat {
    
            mode_t     st_mode;       //文件对应的模式,文件,目录等
            ino_t      st_ino;       //inode节点号
            dev_t      st_dev;        //设备号码
            dev_t      st_rdev;       //特殊设备号码
            nlink_t    st_nlink;      //文件的连接数
            uid_t      st_uid;        //文件所有者
            gid_t      st_gid;        //文件所有者对应的组
            off_t      st_size;       //普通文件,对应的文件字节数
            time_t     st_atime;      //文件最后被访问的时间
            time_t     st_mtime;      //文件内容最后被修改的时间
            time_t     st_ctime;      //文件状态改变时间
            blksize_t st_blksize;    //文件内容对应的块大小
            blkcnt_t   st_blocks;     //文件内容对应的块数量
    
          };
    

    我们可以看到,ino_t返回了文件的i-Node值,编写一个函数如下:

    ino_t get_inode(char *file_name)
    {
        struct stat file;
        int i=stat(file_name,&info);
        return file.st_ino;//返回i-Node值
    }
    

    接下来就需要思考,pwd打印的是绝对路径,直至根目录,那么如何判断已经到达根目录?根目录的...的i-Node值是一样的,在我的电脑上他们都是2。

    伪代码:

    void get_file_name(*filepath){
        获取当前i-Node;
        通过i-Node获取当前路径名称filepath(%s);
        
        cd ..;
        获取当前i-Node;
        通过i-Node获取当前路径名filepath称(%s);
        get_file_name(*filepath);
        if(..i-Node == . i-Node){
        return;
        }
        printf('/'+filename);
        return;
    }
    

    测试代码:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <pwd.h>
    
    
    
    
    void printpath(ino_t this_inode) {
        ino_t my_inode=get_inode(".");
        int buflength=20;
        
        if (get_inode("..") != this_inode) {
            chdir(".."); 
            char path[buflength]=inode_to_path(this_inode,buflength);
            my_inode = get_inode("."); 
            printpath(my_inode);
            printf("/%s", name); 
        }
    }
    
    char * inod_to_path(ino_t i_node, int buflen) {
        DIR *dir; 
        struct dirent *direntp; 
        dir = opendir(".");
        char path[buflen];
        while ((direntp = readdir(dir)) != NULL)
            if (direntp->d_ino == i_node) {
                strncpy(name, direntp->d_name, buflen);
                path[buflen - 1] = ''; 
                closedir(dir);
                return buflen;
            }
        
        exit(1);
        
    }
    
    
    ino_t get_inode(char *filename) {   //返回文件的i-Node值
        struct stat file;
        
        if (stat(filename, &info) == -1) {
            perror(fname);
            return 1;
        }
        return file.st_ino;
    }
    
    int main() {
        printpath(get_inode(".")); 
        putchar('
    '); 
        return 0;
    }
    
    

    代码调试中的问题:

    • 问题1:最开始无法打印出路径名称,总是打印乱码
    • 问题1解决方案:路径名称存储在字符串中,字符串的结尾是'',在查询路径名称时需要给名称的name[length-1]赋值''
    path[buflen - 1] = '';
    
  • 相关阅读:
    macOS 上配置 Lua
    Oracle.ManagedDataAccess.dll
    offer
    Costura.Fody
    日志系统
    实战框架ABP
    什么是算法?
    HTTP状态码->HTTP Status Code
    How to untar a TAR file using Apache Commons
    python实践3:cursor() — 数据库连接操作
  • 原文地址:https://www.cnblogs.com/zhuohua/p/7858522.html
Copyright © 2011-2022 走看看