2017-2018-1 20155321 《信息安全系统设计基础》课堂实践——实现mypwd

学习pwd命令

  • pwd命令:输出当前工作目录的绝对路径

  • 还可通过man pwd具体查看pwd的详细用法

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

  • 通过输入命令man -k directory | grep 2寻找可以实现打印当前目录的系统调用函数,根据结果发现getcwd()函数可以实现此功能

  • 通过命令man getcwd查看此函数的具体用法(包括其需要用到的头文件#include <unistd.h>和此函数相应的参数)

  • 因此可得到相应的伪代码:

定义一个char数组用来保存当前目录的绝对路径;
调用内核函数```getcwd()```获取当前目录的绝对路径并保存至数组中;
if(返回的指针==NULL)
调用函数中存在错误,输出错误警告;
else
直接打印结果

实现mypwd

  • 根据上述的伪代码可得到以下代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char buf[1024], *cwd =getcwd(buf, sizeof(buf));
if (cwd == NULL)
{
printf("error!\n");
exit(1);
}
else
printf("%s\n", cwd);
return 0;
}

测试mypwd

  • 编译并运行可得到正确结果

实验反思

  • 上述做法是直接调用了系统函数,没有涉及到文件系统的细节知识,在Linux系统上,一个文件a可抽象为三个层次,如下图所示:

  • 关于i-nodei-node存储着根文件线管的属性信息以及指向该文件内容数据块的指针信息。一个i-node使用一个整数值(inode-number)来代表一个文件,该值对于一个文件系统而言是唯一的,即通过该值可以找到其对应的i-node。一般情况下,一个文件只有一个inode信息来描述它。
  • 接下来就要获得i-node,可用stat()函数进行实现,stat()函数的相关信息以及stat结构体如下所示:



  • 打印i-node信息的相关代码如下
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
int main(int argc, char* argv[])
{
struct stat file_stat;
if (stat(argv[1], &file_stat) != 0)
{
printf("error!\n");
exit(0);
}
else
{
struct stat *fs = &file_stat;
printf("inode: \t\t\t\t%ld\n", fs->st_ino);
printf("protection: \t\t\t%o\n", fs->st_mode);
printf("number of hard links: \t\t%lu\n", fs->st_nlink);
printf("user ID of owner: \t\t%d\n", fs->st_uid);
printf("group ID of owner: \t\t%d\n", fs->st_gid);
printf("file size in bytes: \t\t%ld\n", fs->st_size);
printf("time of last access: \t\t%s", ctime(&fs->st_atime));
printf("time of last modification: \t%s", ctime(&fs->st_mtime));
printf("time of last change: \t\t%s", ctime(&fs->st_ctime));
}
return 0;
}
  • 打印了mypwd.c文件的i-node信息,如下所示:

  • Linux系统中,目录A包含文件b,从文件系统的角度理解就是目录A的内容列表里有一个文件b的列表项,即binode-numberb``````filename

  • 用此方法实现pwd命令的伪代码如下所示:

  while(1)
{
通过文件名”.”获取当前目录的inode-number
通过文件名”..”获取当前目录的上一级目录的inode-number
if(当前目录的inode-number==上级目录的inode-number)
{
输出完整路径; //说明已是根目录
退出程序 ;
}
else
{
切换至父级目录获取并的inode-number
在父级目录中搜索对应的文件名并记录下来
}
}
  • 实验代码如下
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h> //根据文件名获取文件inode-number
ino_t get_ino_byname(char *filename)
{
struct stat file_stat;
if (stat(filename, &file_stat) != 0)
{
printf("error!\n");
exit(0);
}
return file_stat.st_ino;
} //根据inode-number ,在当前目录中查找对应的文件名
char* find_name_byino(ino_t ino)
{
DIR *dp = NULL;
struct dirent *dptr = NULL;
char *filename = NULL;
if (NULL == (dp = opendir(".")))
{
printf("error!\n");
exit(0);
}
else
{
while (NULL != (dptr = readdir(dp)))
{
if (dptr->d_ino == ino)
{
filename = strdup(dptr->d_name);
break;
}
}
closedir(dp);
}
return filename;
} int main(int argc, char *argv[])
{
//记录目录名的栈
char *dir_stack[100];
unsigned current_depth = 0; while(1){
//通过特殊的文件名“.”获取当前目录的inode-number
ino_t current_ino = get_ino_byname(".");
//通过特殊的文件名“..”获取当前目录的父级目录的inode-number
ino_t parent_ino = get_ino_byname(".."); if (current_ino == parent_ino)
break; //到达根目录
//否则切换至父级目录,根据步骤1获取的inode-number,在父级目录中搜索对应的文件名并记录下来
chdir("..");
dir_stack[current_depth++] = find_name_byino(current_ino);
} //输出完整路径名
int i = current_depth-1;
for (i = current_depth-1; i>=0; i--) {
printf("/%s", dir_stack[i]);
}
printf("%s\n", current_depth==0 ? "/" : ""); return 0;
}
  • 实验结果如下,打印当前目录的绝对路径

2017-2018-1 20155321 《信息安全系统设计基础》课堂实践——实现mypwd的更多相关文章

  1. 20155326 2017-2018-1 《信息安全系统设计基础》第2周学习及课堂总结myod

    20155326 2017-2018-1 <信息安全系统设计基础>第1次学习及课堂总结myod 虚拟机之前出了一些问题,然后我重新弄了一个新的虚拟机. 先在虚拟机里面安装了git. 安完以 ...

  2. 20155308《信息安全系统设计基础 嵌入式C语言课堂考试补博客

    20155308<信息安全系统设计基础 嵌入式C语言课堂考试补博客 知识点 置位 ?bits = bits | (1 << 7) ; /* sets bit 7 */ bits |= ...

  3. 20155217 《信息安全系统设计基础》week16课堂测试

    20155217 <信息安全系统设计基础>week16课堂测试 在作业本上完成附图作业,要认真看题目要求并提交作业截图. 在set的过程中,我们需要将hour部分进行赋值,赋值我们采用&q ...

  4. 2017-2018-1 20155232 《信息安全系统设计基础》第十周课堂测试(ch06)补交

    # 2017-2018-1 20155232 <信息安全系统设计基础>第十周课堂测试(ch06)补交 上课时完成测试后在提交的时候,没有提交成功,进行补交. 1.下面代码中,对数组x填充后 ...

  5. 2017-2018-1 20155305 《信息安全系统设计基础》第四周学习总结(课堂提交作业未来得及提交码云链接myod补充博客)

    2017-2018-1 20155305 <信息安全系统设计基础>第四周学习总结(课堂提交作业未来得及提交码云链接myod补充博客) 课堂提交题目要求 编写MyOD.java 用java ...

  6. 2017-2018-1 20155317 《信息安全系统设计基础》课堂实践——实现mypwd

    2017-2018-1 20155317 <信息安全系统设计基础>课堂实践——实现mypwd 1 . 学习使用pwd 很显然pwd命令的意思是打印出该文件当前的绝对路径 2 . 了解pwd ...

  7. 2017-2018-1 20155330 《信息安全系统设计基础》第10周课堂测试&课下作业

    2017-2018-1 20155330 <信息安全系统设计基础>第10周课堂测试&课下作业 stat命令的实现-mysate 学习使用stat(1),并用C语言实现 提交学习st ...

  8. 20155216 2017-2018-1 《信息安全系统设计基础》第二周课堂练习补交以及Myod的实现

    20155216 2017-2018-1 <信息安全系统设计基础>第二周课堂练习补交 课堂测试3:行断点的设置 运行截图: 未完成原因:课前未安装 cgdb 具体步骤: 1.输入命令:gc ...

  9. 20155305《信息安全系统设计基础》10月18日课堂 fork,exic,wait

    20155305<信息安全系统设计基础>10月18日课堂 fork,exic,wait fork()函数 1.fork函数作用 一般来讲, 我们编写1个普通的c程序, 运行这个程序直到程序 ...

随机推荐

  1. Win8.1下运行环境/配置问题解决方案总结

    目录 1.运行 adb shell 时报错" adb server version (26) doesn't match this client (39); killing... " ...

  2. 对Java中的异常的理解

    1.What is exception in Java? Java使用异常描述程序中可能出现的不正常情况.这个不正常可以是java认为的不正常,也可以是你主观上的出乎意料(自定义异常).总而言之,异常 ...

  3. P2059 [JLOI2013]卡牌游戏

    题目描述 N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先把 ...

  4. MyBatis(3)-映射文件

    本次博文有疑问,请先看MyBatis(1)-简单入门 和 MyBatis(2)-全局配置文件! 如在有疑问,请留言或者咨询博主,博主每天都在!谢谢! 映射文件: 主要是在xxxmapper.xml文件 ...

  5. .Net Sokcet 异步编程

    一.概述 使用Socket 进行实时通讯,如果使用APM,只需要一个Socket类即可.如果使用EAP,则还需要一个SocketAsyncEventArgs类.本文以EAP的方式展开讨论. Socke ...

  6. Springboot中使用ibatis输出日志

    logging.level.org.apache.ibatis=DEBUG logging.level.org.mybatis=DEBUG logging.level.java.sql.Connect ...

  7. Dubbo实践(十四)生产者发布服务

    Export发布服务流程 Dubbo协议向注册中心发布服务:当服务提供方,向dubbo协议的注册中心发布服务的时候,是如何获取,创建注册中心的,如何注册以及订阅服务的,下面我们来分析其流程. 看如下配 ...

  8. vlc源码分析(四) 调用libts接收TS流

    代码分析前,先要了解TS流基本概念:TS流之基本概念. VLC解析TS流是通过libts库来分离的,libts库使用libdvbpsi库来解TS表.VLC使用模块加载机制来加载libts库,具体调用的 ...

  9. linux内存管理--用户空间和内核空间

    关于虚拟内存有三点需要注意: 4G的进程地址空间被人为的分为两个部分--用户空间与内核空间.用户空间从0到3G(0xc0000000),内核空间占据3G到4G.用户进程通常情况下只能访问用户空间的虚拟 ...

  10. Python 学习笔记(十三)Python函数(二)

    参数和变量 >>> def foo(a,b): #函数是一个对象 return a+b >>> p =foo #对象赋值语句.将foo函数赋值给p这个变量 > ...