2017-2018-1 20155330 《信息安全系统设计基础》加分项目--实现mypwd
2017-11-19 17:15
513 查看
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 20155315 《信息安全系统设计基础》加分作业:实现mypwd
- 2017-2018-1 20155336 《信息安全系统设计基础》加分作业:实现mypwd
- 20155326 2017-2018-1 《信息安全系统设计基础》课下加分项mypwd实现
- 2017-2018-1 20155233 《信息安全系统设计基础》实现mypwd
- 2017-2018-1 20155317 《信息安全系统设计基础》课堂实践——实现mypwd
- 2017-2018-1 20155220 《信息安全系统设计基础》课下实践——实现mypwd
- 2017-2018-1 20155226 《信息安全系统设计基础》课下实践——实现mypwd
- 2017-2018-1 20155310 《信息安全系统设计基础》 实现mypwd
- 2017-2018-1 20155210 《信息安全系统设计基础》 实现mypwd
- 2017-2018-1 20155231 《信息安全系统设计基础》实现mypwd
- 2017-2018-1 20155216 《信息安全系统设计基础》 实现mypwd
- 2017-2018-1 20155321 《信息安全系统设计基础》课堂实践——实现mypwd
- 2017-2018-1 20155321 20155330《信息安全系统设计基础》实验三——实时系统
- 2017-2018-1 20155214 《信息安全系统设计基础》 第9周课下测试-mypwd
- 2017-2018-1 20155321 20155330 《信息安全系统设计基础》实验四——外设驱动程序设计
- #2017-2018-1 20155327 《信息安全系统设计基础》实现mypwd
- 2017-2018-1 20155321 20155330 《信息安全系统设计基础》实验四——外设驱动程序设计
- 2017-2018-1 20155321 20155330 《信息安全系统设计基础》实验三——实时系统
- 2017-2018-1 20155201 《信息安全系统设计基础》 pwd命令的实现
- 2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现