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. 转:Window_Open详解

       引:Window_Open详解一.window.open()支持环境:JavaScript1.0+/JScript1.0+/Nav2+/IE3+/Opera3+ 二.基本语法:window.op ...

  2. 山寨"每日故宫"应用的图层遮罩效果

    山寨"每日故宫"应用的图层遮罩效果 最终效果: 应用中的效果: 素材图片: 源码: // // ViewController.m // 每日故宫 // // Created by ...

  3. Linux vim命令详解

    vi: o  处于下一行编辑模式 A  处于编辑的后面  ==>END gg 文件的开头 98gg 跳转到第98行 Shift + G 文件结尾 $ 文件行结尾 ^ 文件行开头   ==> ...

  4. 安装启动apache2.4后报Invalid command 'order', perhaps misspelled or defined by a module not included

    httpd.conf中修改 重启Apache 报错. 在网上搜索了一下,大多是说mod_authz_host.so模块没有加载,但检查后发现httpd.conf中: 该模块并未被注释掉,那原因究竟出在 ...

  5. 铁乐学python_day01-作业

    第一题:使用while循环输入 1 2 3 4 5 6 8 9 10 # 使用while循环输入 1 2 3 4 5 6 8 9 10 count = 0 while (True) : count = ...

  6. [T-ARA][Goodbye, OK]

    歌词来源:http://music.163.com/#/song?id=22704437 作曲 : 안영민 , 이유진 [作曲 : a-nyeong-min , i-yu-jin] 作词 : 안영민 ...

  7. Spring+Hibernate实现动态SessionFactory切换

    场景: 1)系统有多个数据库 2)且数据库类型也不尽相同 3)现在应用根据某些条件路由到具体的数据库 4)且在spring+hibernate框架下,支持依赖注入 已有实现,spring动态数据源,但 ...

  8. 在C#应用程序中,利用表值参数过滤重复,批量向数据库导入数据,并且返回重复数据

    在很多情况下,应用程序都需要实现excel数据导入功能,数据如果只有几十条,或上百条,甚至上千条,速度还好. 但是不仅如此,如果客户提供给你的excel本身存在着重复数据,或是excel中的某些数据已 ...

  9. 纯css3云彩动画效果

      效果描述: 纯CSS3实现的云彩动画飘动效果 非常逼真实用 使用方法: 1.将body中的代码部分拷贝到你的页面中 2.引入对应的CSS文件即可

  10. hdu2824 The Euler function(欧拉函数个数)

    版权声明:本文为博主原创文章,未经博主同意不得转载. vasttian https://blog.csdn.net/u012860063/article/details/36426357 题目链接:h ...