实现mypwd

要求:

学习pwd命令

研究pwd实现需要的系统调用(man -k; grep),写出伪代码

实现mypwd

测试mypwd

pwd:

在Linux层次结构中,想要知道当前所处的目录,可以用pwd命令,该命令显示整个路径名。全称是Print Working Directory。这条命令是一条shell内建命令,并且在大多数shell中都可以使用。

pwd的实现:

  • pwd以绝对路径打印当前的工作目录。因为整个系统的文件组织是树形的,所以,可以从当前目录逐层向根目录进行查找,当找到根目录,即可得到完全路径。

1.如何逐层查找?

  • 系统通过inode节点来管理文件,所以每个文件会有一个inode号。目录是比较特殊的文件,通过<inode, name>的列表组织目录下的文件。每个目录下有两个特殊的文件名".", "..",分别表示当前目录和父目录。

2.如何知道到了根目录?

  • 到达根目录说明没有父目录了,但是".", ".."还是存在于根目录,只是其inode号是相同的。

3.如何打破文件系统的限制,形成完整的绝对路径?

  • 查看系统所有的挂载路径,将所有挂载路径和上面求得的路径拼接起来,如果是合法路径且inode号与最初目录的inode号相同,即是想要的最终的路径。

man -k directory | grep 2可以寻找实现打印当前目录的系统调用函数

伪代码
  1. 根据文件名获取文件的inode-number
  2. stat()通过文件名filename获取文件信息,并保存在buf所指的结构体stat
  3. 根据inode-number, 在当前目录中查找对呀的文件名
  4. opendir()打开一个目录,在失败的时候返回一个空的指针,成返回DIR结构体
  5. readdir()用来读取目录。返回是dirent结构体指针
  6. strdup()将串拷贝到新建的位置处,返回一个指针,指向为复制字符串分配的空间;如果分配空间失败,则返回NULL
  7. 主函数中获取路径并打印

代码实现

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dirent.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. /*根据文件名获取文件inode-number*/
  9. ino_t get_ino_byname(char *filename)
  10. {
  11. struct stat file_stat;
  12. if (0 != stat(filename, &file_stat)) {
  13. perror("stat");
  14. exit(-1);
  15. }
  16. return file_stat.st_ino;
  17. }
  18. /*根据inode-number ,在当前目录中查找对应的文件名*/
  19. char* find_name_byino(ino_t ino)
  20. {
  21. DIR *dp = NULL;
  22. struct dirent *dptr = NULL;
  23. char *filename = NULL;
  24. if (NULL == (dp = opendir("."))) {
  25. fprintf(stderr, "Can not open Current Directory\n");
  26. exit(-1);
  27. } else {
  28. while (NULL != (dptr = readdir(dp))) {
  29. if (dptr->d_ino == ino) {
  30. filename = strdup(dptr->d_name);
  31. break;
  32. }
  33. }
  34. closedir(dp);
  35. }
  36. return filename;
  37. }
  38. /*限制最大的目录深度*/
  39. #define MAX_DIR_DEPTH (256)
  40. int main(int argc, char *argv[])
  41. {
  42. /*记录目录名的栈*/
  43. char *dir_stack[MAX_DIR_DEPTH];
  44. unsigned current_depth = 0;
  45. for(;;) {
  46. /*1.通过特殊的文件名“.”获取当前目录的inode-number*/
  47. ino_t current_ino = get_ino_byname(".");
  48. /*2.通过特殊的文件名“..”获取当前目录的父级目录的inode-number*/
  49. ino_t parent_ino = get_ino_byname("..");
  50. /*3.判断当前目录和上级目录的inode-number是否一样*/
  51. if (current_ino == parent_ino)
  52. break; /*4.如果两个inode-number一样说明到达根目录*/
  53. /*5.如果两个inode-number不一样*/
  54. /*切换至父级目录,根据步骤1获取的inode-number,在父级目录中搜索对应的文件名并记录下来, 重新回到步骤1*/
  55. chdir("..");
  56. dir_stack[current_depth++] = find_name_byino(current_ino);
  57. if (current_depth>=MAX_DIR_DEPTH) { /*路径名太深*/
  58. fprintf(stderr, "Directory tree is too deep.\n");
  59. exit(-1);
  60. }
  61. }
  62. /*输出完整路径名*/
  63. int i = current_depth-1;
  64. for (i = current_depth-1; i>=0; i--) {
  65. fprintf(stdout, "/%s", dir_stack[i]);
  66. }
  67. fprintf(stdout, "%s\n", current_depth==0?"/":"");
  68. return 0;
  69. }

测试pwd

2018-2019-1 20165231 实现mypwd(选做)的更多相关文章

  1. 20155228 2017-11-19 实现mypwd(选做,加分)

    20155228 2017-11-19 实现mypwd(选做,加分) 题目和要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd ...

  2. 20155239 2017-11-19 实现mypwd(选做,加分)

    20155239 2017-11-19 实现mypwd(选做,加分) 题目和要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd ...

  3. 实现mypwd(选做)

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

  4. 课下选做作业实现mypwd

    2019-2020-1 20175227 <信息安全系统设计基础> 课下选做作业实现mypwd 要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 ...

  5. (选做)实现mypwd

    选做 实现mypwd 实验内容: 1.学习pwd命令. 2.研究pwd实现需要的系统调用(man -k; grep),写出伪代码. 3.实现mypwd. 4.测试mypwd. 实验步骤: 学习pwd命 ...

  6. 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...

  7. COCI 2018/2019 CONTEST #2 T4 Maja T5Sunčanje Solution

    COCI 2018/2019 CONTEST #2 T4 T5 Solution abstract 花式暴力 #2 T5 Sunčanje 题意 按顺序给你1e5个长方形(左下角坐标&& ...

  8. Atcoder 水题选做

    为什么是水题选做呢?因为我只会水题啊 ( 为什么是$Atcoder$呢?因为暑假学长来讲课的时候讲了三件事:不要用洛谷,不要用dev-c++,不要用单步调试.$bzoj$太难了,$Topcoder$整 ...

  9. 课下选做作业MySort

    20175227张雪莹 2018-2019-2 <Java程序设计> 课下选做作业MySort 要求 注意:研究sort的其他功能,要能改的动代码,需要答辩 模拟实现Linux下Sort ...

  10. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

随机推荐

  1. Servlet开发笔记(二)

    ServletContext对象 WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用.        ServletConfig对象中维 ...

  2. 软工+C(4): Alpha/Beta换人

    // 上一篇:超链接 // 下一篇:工具和结构化 注:在一次软件工程讨论课程进度设计的过程中,出现了这个关于 Alpha/Beta换人机制的讨论,这个机制在不同学校有不同的实施,本篇积累各方观点,持续 ...

  3. Python之多线程多进程

    (一)进程 1.定义 进程:就是一组资源的集合.一个程序就是一个进程. 线程是用来干活的,只有进程的话是没办法运行的,进程里其实是线程在具体干活的. import threading import t ...

  4. FreeMarker 入门

    目录 FreeMarker是什么 为什么要学习FreeMarker FreeMarker相关站点

  5. gVim编辑器 操作篇

    gVim是一款强大的编辑器,可以满足大部分语言的编程需要.尤其是其自带的模板定制功能对于Verilog来说非常受用.然而gVim有很多操作是不同于其他编辑器的,这让很多初学者望而却步,因此,本文将gV ...

  6. Navicat 连接VMware中Ubuntu 下的mysql5.7遇到的坑

    1.用Navicat连接虚拟机下的mysql出现问题: 2003- Can't connect MySQL Server on '192.168.*.*'(10038). 解决方案: 方法:直接授权( ...

  7. 函数中的this与argument对象,以及argument中的callee与caller属性

    相关阅读:https://segmentfault.com/a/1190000015438195 相关阅读: https://zhuanlan.zhihu.com/p/23804247 相关阅读: h ...

  8. 【地图功能开发系列:二】根据地址名称通过百度地图API查询出坐标

    根据地址名称通过百度地图API查询出坐标 百度地图ApiUrl string url = "http://api.map.baidu.com/geocoder?address={0}& ...

  9. [rhel]安装oracle11g

    https://www.linuxidc.com/Linux/2017-04/142562.htm

  10. windows下提权基础

    拿到webshell很多时候代表渗透的开始,下面带来windows提权基础 环境:虚拟机 win7系统 首先:查看权限whoami 我们知道windows的高权限应该是administrator和sy ...