2017-2018-1 20155205 实现mypwd

课堂总结

根据上课对ls -l功能的实现,我总结了实现一个linux命令需要的步骤:

  1. 使用man -k xx | grep xx查看帮助文档,这里需要查看相关函数的参数、返回值和头文件,同时也要看一下SEE ALSO里与我们查找的功能相关的其他函数。
  2. 借鉴实现其他命令的思路,比如实现myod时,我们要opendir、readdir和closedir,其实每个命令都需要执行这两步,我们就可以按这个思路来写其他的命令。

mypwd的实现

  1. 查看pwd帮助文档,看到一个getcwd,又查看了一下getcwd帮助文档发现这个函数可以直接获取当前路径!

参考getcwd()函数的用法的代码可以实现pwd的功能。

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<unistd.h>
  4. int main(void)
  5. {
  6. char *path = NULL;
  7. path = getcwd(NULL,0);
  8. puts(path);
  9. free(path);
  10. return 0;
  11. }

2.按照老师上课的教学内容,我们还可以用stat来实现pwd。

首先在学习过程中,我们知道了上一级“.”和上上级“..”的结点信息的关系。

先看一下stat中的结构体,可以看到ino_t是存储结点数的,所以我们编程序要用到它。

  1. struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is NOT defined */
  2. dev_t st_dev; /* device inode resides on */
  3. ino_t st_ino; /* inode's number */
  4. mode_t st_mode; /* inode protection mode */
  5. nlink_t st_nlink; /* number of hard links to the file */
  6. uid_t st_uid; /* user-id of owner */
  7. gid_t st_gid; /* group-id of owner */
  8. dev_t st_rdev; /* device type, for special file inode */
  9. struct timespec st_atimespec; /* time of last access */
  10. struct timespec st_mtimespec; /* time of last data modification */
  11. struct timespec st_ctimespec; /* time of last file status change */
  12. off_t st_size; /* file size, in bytes */
  13. quad_t st_blocks; /* blocks allocated for file */
  14. u_long st_blksize;/* optimal file sys I/O ops blocksize */
  15. u_long st_flags; /* user defined flags for file */
  16. u_long st_gen; /* file generation number */
  17. };

上网查了相关资料后,发现我们还需要掌握一个DIR结构体:

  1. struct __dirstream
  2. {
  3. void *__fd; // `struct hurd_fd' pointer for descriptor.
  4. char *__data; // Directory block.
  5. int __entry_data; // Entry number `__data' corresponds to.
  6. char *__ptr; // Current pointer into the block.
  7. int __entry_ptr; // Entry number `__ptr' corresponds to.
  8. size_t __allocation;// Space allocated for the block.
  9. size_t __size; // Total valid data in the block.
  10. __libc_lock_define (, __lock) // Mutex lock for this structure.
  11. };
  12. typedef struct __dirstream DIR;

DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息。函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用:

  1. struct dirent *readdir(DIR *dp);
  2. void rewinddir(DIR *dp);
  3. int closedir(DIR *dp);
  4. long telldir(DIR *dp);
  5. void seekdir(DIR *dp,long loc);

接着是dirent结构体,首先我们要弄清楚目录文件(directory file)的概念:这种文件包含了其他文件的名字以及指向与这些文件有关的信息的指针。从定义能够看出,dirent不仅仅指向目录,还指向目录中的具体文件,readdir函数同样也读取目录下的文件,这就是证据。以下为dirent结构体的定义:

  1. struct dirent
  2. {
  3.   long d_ino; /* inode number 索引节点号 */
  4.   
  5. off_t d_off; /* offset to this dirent 在目录文件中的偏移 */
  6.   
  7. unsigned short d_reclen; /* length of this d_name 文件名长 */
  8.   
  9. unsigned char d_type; /* the type of d_name 文件类型 */
  10.   
  11. char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
  12. }
  • 伪代码
  1. 获取当前文件名和结点数;
  2. if"."".."结点数不相等)

  3. 打印当前文件名;
  4. cd上一级;

  • 测试代码
  1. #include<stdio.h>
  2. #include<sys/stat.h>
  3. #include<sys/types.h>
  4. #include<dirent.h>
  5. #include<stdlib.h>
  6. #include<string.h>
  7. #define SIZE 128
  8. ino_t getinode(char *dirname); //获取文件名称
  9. void getwork(ino_t inode_num);
  10. void dirname(ino_t inode_num, char *buf, int buflen);
  11. int main(void)
  12. {
  13. getwork(getinode("."));
  14. printf("\n");
  15. return 0;
  16. }
  17. ino_t getinode(char *dirname) //通过stat得到文件名
  18. {
  19. struct stat name;
  20. if (stat(dirname, &name) == -1)
  21. {
  22. perror("dirname");
  23. exit(1);
  24. }
  25. return name.st_ino;
  26. }
  27. void getwork(ino_t inode_num)
  28. {
  29. ino_t parent_inode;
  30. char buf[SIZE];
  31. if (getinode("..") != inode_num)
  32. {
  33. chdir(".."); //到达..文件
  34. dirname(inode_num, buf, SIZE);
  35. parent_inode = getinode(".");
  36. getwork(parent_inode); //此处通过递归来不断到达上一级
  37. printf("/%s", buf);
  38. }
  39. }
  40. void dirname(ino_t inode_num, char *buf,int buflen) //
  41. {
  42. DIR *dir_ptr;
  43. struct dirent *dirt;
  44. if ((dir_ptr = opendir(".")) == NULL)
  45. {
  46. perror(".");
  47. exit(1);
  48. }
  49. while ((dirt = readdir(dir_ptr)) != NULL)
  50. {
  51. if (dirt->d_ino == inode_num)
  52. {
  53. strncpy(buf, dirt->d_name, buflen);
  54. buf[strlen(buf)] = '\0';
  55. closedir(dir_ptr);
  56. return ;
  57. }
  58. }
  59. exit(1);
  60. }
  • 测试结果

2017-2018-1 20155205 实现mypwd的更多相关文章

  1. MyEclips 2017/2018 (mac 版)安装与破解

    MyEclips 2017/2018 (mac 版)安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEclips ...

  2. MyEclipse 2017/2018 安装与破解 图文教程

    SSM 框架-02-MyEclipse 2017/2018 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEc ...

  3. </2017><2018>

    >>> Blog 随笔原始文档及源代码 -> github: https://github.com/StackLike/Python_Note >>> 统计信 ...

  4. 我的2017&2018

    最近项目进入验收阶段,所以上班没那么忙碌了,但是怎么说呢,我可能天生是闲不住的主,觉得浑身不自在(我这样的人是不是特别不会享福),此处应该有个笑脸哈. 翻看了博客园好几个大牛写的技术文章,感慨大牛不愧 ...

  5. [2017 - 2018 ACL] 对话系统论文研究点整理

    (论文编号及摘要见 [2017 ACL] 对话系统. [2018 ACL Long] 对话系统. 论文标题[]中最后的数字表示截止2019.1.21 google被引次数) 1. Domain Ada ...

  6. CorelDRAW X7 X8 2017 2018是什么关系?

    从CorelDRAW 2017版本开始我们叫习惯了的X几系列的CorelDRAW毅然决然的就换了称呼,所以有时候很多朋友对于软件版本,经常会傻傻分不清,还有人认为X8版本比2017版本高,究竟为什么会 ...

  7. JetBrains 2017/2018全系列产品激活工具

    可谓是工欲善其事,必先利其器,相信作为优秀开发工程师的你都想拥有一套快捷高效的编码工具,而JetBrains这家公司的产品,不管是那种编程语言,其开发工具确实让开发者们着迷,JetBrains的产品博 ...

  8. 【LOJ】#2349. 「JOI 2017/2018 决赛」团子制作

    题解 有意思的一个dp,我们对G计数,发现如果不在同一条对角线上的G肯定不会互相影响,所以我们对于每一条对角线dp dp的方式是枚举这个G以什么方式放,横着还是竖着,还是不放 代码 #include ...

  9. 【LOJ】#2350. 「JOI 2017/2018 决赛」月票购买

    题解 首先求一个最短路图出来,最短路图就是这条边在最短路上就保留,否则就不保留,注意最短路图是一个有向图,一条边被保留的条件是 dis(S,u) + val(u,v) = dis(v,T)我们需要求两 ...

随机推荐

  1. jsTree树形菜单分类

    这里我演示的jsTree是基于ABP框架 ,展示部分代码,话不多说首先看效果如: 1:引入JS <link href="/jstree/themes/default/style.css ...

  2. 浏览器全屏之requestFullScreen全屏与F11全屏

    一.简介 浏览器全屏有两种方式,一种是HTML5新增的requestFullscree全屏,另一种是摁F11实现的全屏,本文将详解两种全屏的特点以及实现代码. 二.requestFullscreen全 ...

  3. Spring中的IOC和AOP是什么含义,他们在项目中起到什么作用,并举例说明?

    IOC:控制反转,是一种设计模式.一层哈尼是控制权的转移:由传统的在程序中控制并依赖转移到容器赖控制:第二是依赖注入:将相互以来的对象分离,在Spring配置文件中描述他们的依赖关系.他们的依赖关系只 ...

  4. [BZOJ1385] [Baltic2000] Division expression (数学)

    Description 除法表达式有如下的形式: X1/X2/X3.../Xk 其中Xi是正整数且Xi<=1000000000(1<=i<=k,K<=10000) 除法表达式应 ...

  5. iptables 学习

    本博客是学习慕课网课程 用iptables搭建一套强大的安全防护盾 整理而成 iptables相当于在ip层挂载一个hook point对用户进行控制 组成: 四张表+ 五条链(hook point) ...

  6. Several ports (8005, 8080, 8009)被占用

    启动Tomcat服务器报错: Several ports (8005, 8080, 8009) required by Tomcat v5.5 Server at localhost are alre ...

  7. Redis学习日记-01

    Redis是什么东东? Redis是用C语言开发的Key-Value数据库,说是数据库,其实他是NoSql(非关系型数据库). 这里顺便说一下Sql(关系型数据库,如MySql,Oracle等)和No ...

  8. js备战春招の四の严格模式

    JavaScript 严格模式(strict mode)即在严格的条件下运行. use strict 严格模式下你不能使用未申明的变量 "use strict" 指令只运行出现在脚 ...

  9. android studio运行的时候出现Unable to obtain debug bridge错误的解决办法

    先贴上我百度的: 首先利用win+R,输入cmd,并且输入命令好来到:cd D:\Android\sdk\platform-tools\(这个是我的adb.exe目录,你的可以自行搜索)然后输入:ad ...

  10. 20165230 2017-2018-2 《Java程序设计》第3周学习总结

    20165230 2017-2018-2 <Java程序设计>第3周学习总结 教材学习内容总结 本周主要学习了类与对象. 包括创建对象与构造方法. 了解了程序是由若干个类所构成:类分为类名 ...