• 实现mypwd(选做)


    实现mypwd(选做)

    任务清单
    1 学习pwd命令
    2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码
    3 实现mypwd
    4 测试mypwd
    

    (一)pwd命令的学习

    1、pwd的功能

    • 通过查询man手册可知,pwd用于打印当前目录的整个路径名,即目录的绝对地址;

      • 扩展:
        • 绝对路径:目录下的绝对位置,直接到达目标位置,通常是从盘符开始的路径。完整的描述文件位置的路径就是绝对路径;
        • 相对路径:相对于当前文件的路径;
        • LINUX系统中:
          • 绝对路径:以“/”为起始。例:/home/user1/abc.txt
          • 相对路径为: home/user1/abc.txt

    2、pwd使用示例

    (二)pwd需要的系统调用

    • 由于pwd与目录、路径有关,输入man -k directory |grep 2,查询与目录有关的系统调用;

    • 由查询结果可知有三个系统调用是可能符合结果的,分别进入对应man手册页进行查看:

    • chdir:改变当前所处目录

    • getcwd:获得当前所在目录路径

    • readdir:获得目录条目

    • 其中,很明显getcwd完美符合pwd的需求,一个获取,一个打印,由此可以轻松写出以下代码:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main()
    {
        char dir[1000];
        char *cwd=getcwd(dir, sizeof(dir));
        if (cwd==NULL)
        {
            perror("Can't get directory!
    ");
            return -1;
        }
        else
        {
            printf("%s
    ", cwd);
        }
        return 0;
    }
    
    • 最终效果

    • 但是这种实现方式是取巧的,所以接下来还是要继续深入学习一下:

      • 通过另两个查询出的系统调用,可以联想出另一个思路:先通过readdir获取当前目录名称,然后通过chdir向上搜寻父目录,之后不断循环此流程直至根目录;
      • 但这又引出了另一个问题,readdir读的是什么呢?
      • 重新打开readdir的手册页,可以看到这一行:

    • 再使用man inode查询一下inode是干什么的:


    • 由此可见,inode是文件系统中的meta data,文件索引节点,是文件基本信息的存放地和数据块指针存放地。且每一个文件都有一个独一无二的inode number。linux文件系统通过inode表进行文件的管理。
    • 综上,可以写出一个基于inode的pwd伪代码,其基本思想是递归:
    while(未到根目录)
        {
          读取当前目录名称;
          打开父目录;
        }
    printf(目录);
    

    (三)实现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("
    ");
            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)] = '';
                    closedir(dir_ptr);
                    return ;
                }
            }
            fprintf(stderr, "error looking for inode number %d
    ", (int)inode_num);
            exit(1);
        }
    

    (四)测试pwd

  • 相关阅读:
    《卓有成效的管理者》读后感
    小课堂week13 Clean Code Part2
    小课堂Week12 Clean Code Part1
    小课堂Week11 会说话的代码
    小课堂Week10 例外处理设计的逆袭Part3
    Spark菜鸟学习营Day6 分布式代码运行调试
    UML(一) 类图及类间关系
    分布式事务(一)两阶段提交及JTA
    Java线程间通信方式剖析——Java进阶(四)
    Java进阶(三)多线程开发关键技术
  • 原文地址:https://www.cnblogs.com/fzlzc/p/12026705.html
Copyright © 2020-2023  润新知