实现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!\n");
return -1;
}
else
{
printf("%s\n", 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("\n");
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)] = '\0';
closedir(dir_ptr);
return ;
}
}
fprintf(stderr, "error looking for inode number %d\n", (int)inode_num);
exit(1);
}

(四)测试pwd

实现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

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

  4. (选做)实现mypwd

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

  5. [SDOI2016]部分题选做

    听说SDOI蛮简单的,但是SD蛮强的.. 之所以是选做,是因为自己某些知识水平还不到位,而且目前联赛在即,不好花时间去学sa啊之类的.. bzoj4513储能表&bzoj4514数字配对 已写 ...

  6. 20175221 《Java程序设计》迭代和JDB(课下作业,选做):

    20175221 <Java程序设计> 迭代和JDB(课下作业,选做): 任务详情 1 使用C(n,m)=C(n-1,m-1)+C(n-1,m)公式进行递归编程实现求组合数C(m,n)的功 ...

  7. MyOD(课下作业,选做)

    MyOD(课下作业,选做) 代码要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.b ...

  8. 迭代和JDB(课下作业,选做)

    迭代和JDB(课下作业,选做) 题目要求 1 使用C(n,m)=C(n-1,m-1)+C(n-1,m)公式进行递归编程实现求组合数C(m,n)的功能 2 m,n 要通过命令行传入 3 提交测试运行截图 ...

  9. 20175312 2018-2019-2 《Java程序设计》第6周课下选做——类定义

    20175312 2018-2019-2 <Java程序设计>第6周课下选做--类定义 设计思路 1.我觉得Book其实就是一个中转的作用,由测试类Bookself通过Book输入数据,然 ...

随机推荐

  1. python-day12(正式学习)

    目录 可变长参数 可变长形参之* 可变长实参之* 可变长形参之** 可变长实参之** 可变长参数应用 命名关键字形参 函数对象 四大功能 引用 当作参数传给一个函数 可以当作函数的返回值 可以当作容器 ...

  2. php 数组助手类

    ArrayHelper.php <?php /** * php 数组助手类 * Class ArrayHelper * @package app\helper */ class ArrayHel ...

  3. chromedriver.exe下载

    淘宝的镜像地址可以下载: https://npm.taobao.org/mirrors/chromedriver/

  4. vuex的简单理解

    初次接触vuex,谈谈我自己的理解.有待后期改进 首先要知道,Vuex 是专门为 Vue.js 设计的状态管理库.我们知道在用vue.js进行前端项目开发时,会出现很多组件相互之间调用属性.状态,小项 ...

  5. 错误 “SCRIPT7002: XMLHttpRequest: 网络错误 0x2ef3, ie浏览器兼容问题

    参考:https://www.telerik.com/blogs/help!-running-fiddler-fixes-my-app- https://www.cnblogs.com/OpenCod ...

  6. JS计算两个经纬度的距离

    var mapNumberUtil = {}; /** * 计算两个经纬度的距离(千米) */mapNumberUtil.getDistance = function(lat1, lng1, lat2 ...

  7. SpringBoot项目中遇到的BUG

    1.启动项目的时候报错 1.Error starting ApplicationContext. To display the auto-configuration report re-run you ...

  8. Vmware 安装 ghost 版 win 7

    很早就弄过vmware,很可惜一直没有仔细研究过,这次要安装一个win7系统,重新又学一下了一下,下面说一下安装的操作步骤吧. 第一步,下载vmware,原版的下载地址就不说了,上传到百度网盘自己下载 ...

  9. 关于mysql的查询优化

    由于工作原因,最近甲方客户那边多次反应了他们那边的系统查询速度慢,经过排除之后,发现他们那边的数据库完全没有用到索引,简直坑得一笔,通过慢查询日志分析,为数据表建立了适当的索引之后,查询速度明显的提高 ...

  10. Python Requests库 Get和Post的区别和Http常见状态码

    (1)   在客户端,Get方式在通过URL提交数据,数据在URL中可以看到:POST方式,数据放置在HTML HEADER内提交. (2)   GET方式提交的数据最多只能有1024 Byte,而P ...