2017-2018-1 20155330 《信息安全系统设计基础》加分项目--实现mypwd

pwd命令

  • 命令功能:查看”当前工作目录“的完整路径。

  • 通过man命令查看pwd的相关信息

mypwd的实现

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

  • 通过man -k directory | grep 2查看相关系统调用。可以发现getcwd()函数是实现该功能的相关函数。

  • 通过man 2 getcwd查看函数结构。

  • 利用getcwd()函数简单实现的伪代码
设置一个char型数组(或指针)用于保存当前绝对路径内容;
调用系统函数`getcwd()`获取当前路径并保存在之前的数组中;
if(返回指针==NULL)
错误;
else
打印当前路径;
  • 代码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX 2048 int main()
{
char buf[MAX],*a=getcwd(buf,sizeof(buf));
if(a==NULL)
printf("Error!");
else
printf("%s\n",a);
return 0;
}

运行结果:

  • 通过man -k directory | grep 3查看相关库函数。

  • 通过之前查看的getcwd函数可知getcwd函数与getwd函数基本相同。现在查看opendir()函数和readdir()函数。
    • opendir()函数

    • readdir()函数

  • readdir()函数中的结构体
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* not an offset; see NOTES */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all filesystem types */
char d_name[256]; /* filename */
};

可以知道显示文件名需要与之对应的i-node

  • 获得i-node可用stat函数,需要注意的是,在使用帮助文档查看stat函数时,应使用命令man 2 stat
  • 代码实现查看inode功能
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h> int main(int argc, char *argv[])
{
struct stat sb; if (argc != 2) {
fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
exit(EXIT_FAILURE);
} if (stat(argv[1], &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
} printf("File type: "); switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown?\n"); break;
} printf("I-node number: %ld\n", (long) sb.st_ino); printf("Mode: %lo (octal)\n",
(unsigned long) sb.st_mode); printf("Link count: %ld\n", (long) sb.st_nlink);
printf("Ownership: UID=%ld GID=%ld\n",
(long) sb.st_uid, (long) sb.st_gid); printf("Preferred I/O block size: %ld bytes\n",
(long) sb.st_blksize);
printf("File size: %lld bytes\n",
(long long) sb.st_size);
printf("Blocks allocated: %lld\n",
(long long) sb.st_blocks); printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime)); exit(EXIT_SUCCESS);
}
  • 运行结果
  • 综合以上信息得到伪代码
设置一个char型数组(或指针)用于保存当前绝对路径内容,无符号数用于记录绝对路径的深度;
while(1)
{
分别获取"."(当前目录)和".."(当前目录的上一级目录)i-node;
if("."i-node==".."i-noode)
输出目录信息;
else
{
切换至父级目录获取i-node
在父级目录中搜索对应的文件名并记录下来
}
}
  • 完整代码
#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(0 != stat(filename, &file_stat)) //stat()通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
{
perror("stat");
exit(-1);
} 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("."))) //opendir()打开一个目录,在失败的时候返回一个空的指针,成返回DIR结构体
{
fprintf(stderr, "Can not open Current Directory\n");
exit(-1);
}
else
{
while(NULL != (dptr = readdir(dp))) //readdir()用来读取目录。返回是dirent结构体指针
{
if(dptr->d_ino == ino)
{
filename = strdup(dptr->d_name); //strdup()将串拷贝到新建的位置处,返回一个指针,指向为复制字符串分配的空间;如果分配空间失败,则返回NULL值.
break;
}
} closedir(dp);
} return filename;
} int main(int argc, char *argv[])
{
//记录目名的栈
char *dir_stack[256];
unsigned current_depth = 0; while(1)
{
ino_t current_ino = get_ino_byname("."); //通过"."获取当期目录inode
ino_t parent_ino = get_ino_byname(".."); //通过".."获取当前目录的父目录的inode
if(current_ino == parent_ino)
break; //达到根目录,推出循环 /*若两个inode不一样*/
chdir(".."); //更改当前工作目录,变为当前目录的父目录
dir_stack[current_depth++] = find_name_byino(current_ino); //"文件名"地址存放
} int i = current_depth - 1;
for(i = current_depth - 1; i >= 0; i--) //打印路径
{
fprintf(stdout, "/%s", dir_stack[i]);
}
fprintf(stdout, "%s\n", current_depth == 0 ? "/" : ""); return 0;
}

运行结果:

2017-2018-1 20155330 《信息安全系统设计基础》加分项目--实现mypwd的更多相关文章

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

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

  2. 2017-2018-1 20155336 《信息安全系统设计基础》加分作业:实现mypwd

    2017-2018-1 20155336 <信息安全系统设计基础>加分作业:实现mypwd 什么是PWD? 用man pwd查看: 用于打印当前工作目录的工作路径 1.命令格式:pwd[选 ...

  3. 2017-2018-1 20155320 《信息安全系统设计基础》第四周学习总结(课堂实践补交+myhead与mytail加分项目)

    2017-2018-1 20155320 <信息安全系统设计基础>第四周学习总结(课堂实践补交+myhead与mytail实现) 课堂实践内容 1 参考教材第十章内容 2 用Linux I ...

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

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

  5. # 20145314《信息安全系统设计基础》期中复习总结 Part B

    20145314<信息安全系统设计基础>期中复习总结 Part B 学习知识点内容总结 复习线索:http://group.cnblogs.com/topic/73069.html 本周的 ...

  6. 20145213《信息安全系统设计基础》实验一 Linux开发环境的配置

    北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级:1452 姓名: 黄亚奇 祁玮 学号:20145213 20145222 成绩: 指导教师:娄嘉鹏 实验日期:2016 ...

  7. 20145215&20145307《信息安全系统设计基础》实验二 固件设计

    20145215&20145307<信息安全系统设计基础>实验二 固件设计 实验目的与要求 了解多线程程序设计的基本原理,学习 pthread 库函数的使用. 了解在 linux ...

  8. 20145215&20145307《信息安全系统设计基础》实验五 网络通信

    小组成员:20145215卢肖明.20145307陈俊达 实验报告链接:信息安全系统设计基础--实验五实验报告

  9. 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析

    20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...

随机推荐

  1. PHP生成随机或者唯一字符串

    本文出至:新太潮流网络博客 /** * [生成随机字符串] * @E-mial wuliqiang_aa@163.com * @TIME 2017-04-07 * @WEB http://blog.i ...

  2. twemproxy源码分析

    twemproxy是twitter开源的redis/memcached 代理,数据分片提供取模,一致性哈希等手段,维护和后端server的长连接,自动踢除server,恢复server,提供专门的状态 ...

  3. TreeView控件概述、属性与方法

    1.作用:用于显示Node结点的分层列表.2.添加到控件箱菜单命令:工程 | 部件,在部件对话框中选择:Microsoft Windows Common Controls 6.03.TreeView控 ...

  4. mysql-sql-standard

    https://github.com/zhishutech/mysql-sql-standard

  5. matlab中关于函数句柄、feval函数以及inline函数的解析 (转)

    http://blog.sina.com.cn/s/blog_7bff755b010180l3.html MATLAB函数句柄 函数句柄(Function handle)是MATLAB的一种数据类型. ...

  6. 安装zabbix3.4的过程(一)

    目录 zabbix服务端安装(centos7.4) zabbix客户端安装 (centos6.9) 注释:本次安装为官方推荐的yum安装方式,如果需要编译安装,请查看下边的博文: 博文地址:https ...

  7. October 05th 2017 Week 40th Thursday

    Happiness is to find someone who can give you warm and share your life together. 幸福,就是找一个温暖的人过一辈子. Y ...

  8. NLog写入Mongo日志配置

    Web网站中引入了NLog日志,日志记录在Mongo数据库中,经过两天的简单学习,现简要记录说明下: 首先贴出NLog的学习地址: https://github.com/NLog/NLog/wiki/ ...

  9. 映射函数map

    映射函数map 语法: map(function, iterable) 迭代对象中 的每一个元素进行映射, 分别执行function函数 例子:  ls =[1,2,3,4,5,6] def func ...

  10. 2018.08.30 21:12 第一个Django程序完成

    from django.http import HttpResponse def hello(request): return HttpResponse("Hello world ! &qu ...