第9周 实现PWD命令
码云链接:https://gitee.com/bestiisjava2017/laura5332/blob/master/信息安全系统设计/mybash.c
题目要求
- 1 学习pwd命令
- 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码
- 3 实现mypwd
- 4 测试mypwd
学习pwd命令
-
1:用
man pwd
查看帮助文档
-
2:显示当前目录所在路径 pwd
smile@ubuntu:~/dky5332$ pwd
/home/smile/dky5332
- 3:显示当前目录的物理路径 pwd –P
- 4: 显示当前目录的连接路径:pwd -L
2.研究pwd实现需要的系统调用(man -k; grep),写出伪代码
man-k directory | grep 2
算法核心——伪代码
- 拿到当前目录中"."这个目录的st_ino值,记为inode。
- 转到父目录中,遍历父目录,找到第一个st_ino值与inode相同的那个目录,并保存名字。
- 再拿当前目录中"."目录的st_ino值作为inode,向前递归(此时的"."目录已经不是1中的"."了,而是1中的"..")
- 输出 “/" + 2中保存的名字
递归出口:
由于在根目录下,"." 和 ".." 的inode值是一样的,所以当递归到某一层,若父目录的inode值与当前的inode值(作为递归函数的参数传入) 相同,那么就可以结束递归了。
3.实现pwd命令
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 128
ino_t get_inode(char *dirname);
void get_work_dir(ino_t inode_num);
void inode_to_dirname(ino_t inode_num, char *buf, int buflen);
int main(void)
{
get_work_dir(get_inode("."));
printf("
");
return 0;
}
ino_t get_inode(char *dirname)
{
struct stat info;
if (stat(dirname, &info) == -1)
{
perror("dirname");
exit(1);
}
return info.st_ino;
}
void get_work_dir(ino_t inode_num)
{
ino_t parent_inode;
char buf[SIZE];
if (get_inode("..") != inode_num)
{
chdir("..");
inode_to_dirname(inode_num, buf, SIZE);
parent_inode = get_inode(".");
get_work_dir(parent_inode);
printf("/%s", buf);
}
}
void inode_to_dirname(ino_t inode_num, char *buf,int buflen)
{
DIR *dir_ptr;
struct dirent *dire;
if ((dir_ptr = opendir(".")) == NULL)
{
perror(".");
exit(1);
}
while ((dire = readdir(dir_ptr)) != NULL)
{
if (dire->d_ino == inode_num)
{
strncpy(buf, dire->d_name, buflen);
buf[strlen(buf)] = ' ';
closedir(dir_ptr);
return ;
}
}
fprintf(stderr, "error looking for inode number %d
", (int)inode_num);
exit(1);
}
测试pwd命令