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. [T-ARA][SEXY LOVE]

    歌词来源:http://music.163.com/#/song?id=22704402 作曲 : 新沙洞老虎/崔圭成 [作曲 : 新沙洞老虎/崔圭成] [作曲 : 新沙洞老虎/崔圭成] 作词 : 新 ...

  2. Jackson实现Object对象与Json字符串的互转

    在项目开发过程中,当客户端与服务器响应时,数据交互是必不可少的.然而通过Json实现数据交互成为我们开发中的一部分,进而Jackson为我们的Json转化提供了很好的机制.下面我将利用实例总结如何使用 ...

  3. 数据类型.md

    数据类型 整型 数据类型 含义(有符号) tinyint(m) 1个字节 范围(-128~127) smallint(m) 2个字节 范围(-32768~32767) mediumint(m) 3个字 ...

  4. RedisClient的安装及基本使用

    管理redis的可视化客户端目前较流行的有三个:Redis Client ; Redis Desktop Manager ; Redis Studio. 这里目前给大家介绍Redis Client 的 ...

  5. mysql 聚集和非聚集索引 解析

    一.聚集索引(聚簇索引) 1. 什么是聚集索引? 比如要查找'hello',则直接找内容为hello的行,我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”.   聚集索引的叶子节点 ...

  6. Emacs 快速指南 - 原生中文手册

    Emacs 快速指南 -折叠目录 1. 小结(SUMMARY) 2. 基本的光标控制(BASIC CURSOR CONTROL) 3. 如果 EMACS 失去响应(IF EMACS STOPS RES ...

  7. nginx发布antd-pro项目(别人发的,未测试)

    server { listen ; server_name localhost; #charset koi8-r; charset utf-; #access_log logs/host.access ...

  8. 搞懂JVM类加载机制

    有这样一道面试题: class Singleton{ private static Singleton singleton = new Singleton(); public static int v ...

  9. 使用Fiddler监控来自手机客户端的请求

    环境配置组成: 1 手机 2 安装Fiddler的PC 设置要点: 1 手机和PC应在同一个局域网内 我的做法是:PC安装WIFI热点,手机连接热点上网 PC的IP是192.168.95.1  手机的 ...

  10. +QFTPOPEN: 603,0 怎么把这样一个字符串中的 603 提取出来给一个 uint32_t 的变量那

    +QFTPOPEN: 603,0   怎么把这样一个字符串中的 603 提取出来给一个 uint32_t 的变量那? 注意冒号后面有个空格!!! 答案:要使用 sscanf 标准库函数! char s ...