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] = '';
原文地址:https://www.cnblogs.com/zhuohua/p/7858522.html