选做 实现mypwd

实验内容:

  • 1.学习pwd命令。

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

  • 3.实现mypwd。

  • 4.测试mypwd。

实验步骤:

学习pwd命令

  • man pwd查看pwd功能

  • 该命令用来显示目前所在的工作目录。指令英文原义:print work directory。

    • 显示当前目录所在路径 pwd

    • 显示当前的路径,有连接文件时,不使用连接路径,直接显示连接文件所指向的文件;当包含多层连接文件时,显示连接文件最终指向的文件: pwd –P

    • 显示当前的路径,有连接文件时,直接显示连接文件的路径,(不加参数时默认此方式):pwd -L

    • 显示帮助信息:pwd -help

    • 显示版本信息:pwd -version

研究pwd实现需要的系统调用(man -k; grep)

  • (1)查看相关系统调用函数信息:man -k dir | grep 2

  • (2)可以得知getcwd命令可以获得当前目录路径。man getcwd查看getcwd命令功能。

找到所需要的头文件以及函数

#include <unistd.h>
char *getcwd(char *buf, size_t size);

图中getcwd():getcwd(char *buf,size_t size)是将当前工作目录的绝对路径复制到参数buffer所指的内存空间中,参数size为buf的空间大小。

  • (3)由刚才man -k directory | grep 2获得的相关命令中我们也可以发现chdir命令会被用到。man chdir查看chdir命令功能。

找到所需要的头文件以及函数

#include <unistd.h>
int chdir(const char *path);

图中chdir():int chdir(const char *path )用于改变当前工作目录,调用参数是指向目录的指针,调用进程需要有搜索整个目录的权限。

  • (4)由刚才man -k directory | grep 2获得的相关命令中我们也可以发现readdir命令会被用到。man readdir查看readdir命令功能

找到所需要的头文件以及函数

#include <dirent.h>
struct dirent *readdir(DIR *dirp);

图中readdir():readdir(DIR* dir)返回参数dir 目录流的下个目录进入点。

需要搭配opendir()使用:opendir (const char * path )获取path子目录下的所由文件和目录的列表,如果path是个文件则返回值为NULL。

对于它的实现,我们首先要知道,目录在Linux中其实也是一种文件,所以它也是由inode+数据块构成的,每一个列表记录inode-number+filename

  • (5)伪代码

    • 通过上面我们可以发现可以通过两种函数来实现pwd命令

    • getcwd()

      定义一个缓冲区数组buf[MAXPATH]; 调用getcwd(buf, MAXPATH); 输出返回值即为路经;

    • readdir()

      1. 通过特殊的文件名"."获取当前目录的inode-number(假设当前目录为a)

      2. 通过特殊的文件名".."获取当前目录的父级目录的inode-number

      3. 判断当前目录和上级目录的inode-number是否一样

      4. 如果两个inode-number一样说明达到根目录,输出完整路径,退出程序

      5. 如果两个inode-number不一样,切换至父级目录,根据步骤1获取的inode-number,在父级目录中搜索对应的文件名并记录下来,然后重新回到步骤1

实现mypwd

代码如下:

#include<stdio.h>
#include<sys/stat.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include <unistd.h>
void printpath();
char *inode_to_name(int);
int getinode(char *);
//功能:打印当前目录路径
void printpath()
{
int inode,up_inode;
char *str;
inode = getinode(".");
up_inode = getinode("..");
chdir("..");
str = inode_to_name(inode);
//当当前目录的i-node与父级目录的i-node相同时,到达根目录
if(inode == up_inode) {
return;
}
//打印路径
printpath();
printf("/%s",str);
}
//功能:获取当前目录的i-node
int getinode(char *str)
{
struct stat st;
if(stat(str,&st) == -1){
perror(str);
exit(-1);
}
return st.st_ino;
}
//功能:获取当前路径
char *inode_to_name(int inode)
{
char *str;
DIR *dirp;
struct dirent *dirt;
if((dirp = opendir(".")) == NULL){
perror(".");
exit(-1);
}
while((dirt = readdir(dirp)) != NULL)
{
if(dirt->d_ino == inode){
str = (char *)malloc(strlen(dirt->d_name)*sizeof(char));
strcpy(str,dirt->d_name);
return str;
}
}
perror(".");
exit(-1);
}
//主函数
int main()
{
printpath();
putchar('\n');
return 0;
}

测试mypwd

截图如下:

(选做)实现mypwd的更多相关文章

  1. 20155228 2017-11-19 实现mypwd(选做,加分)

    20155228 2017-11-19 实现mypwd(选做,加分) 题目和要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd ...

  2. 20155239 2017-11-19 实现mypwd(选做,加分)

    20155239 2017-11-19 实现mypwd(选做,加分) 题目和要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 实现mypwd 测试mypwd ...

  3. 课下选做作业实现mypwd

    2019-2020-1 20175227 <信息安全系统设计基础> 课下选做作业实现mypwd 要求 学习pwd命令 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 ...

  4. 实现mypwd(选做)

    实现mypwd(选做) 任务清单 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd (一)pwd命令的学习 1.pw ...

  5. [SDOI2016]部分题选做

    听说SDOI蛮简单的,但是SD蛮强的.. 之所以是选做,是因为自己某些知识水平还不到位,而且目前联赛在即,不好花时间去学sa啊之类的.. bzoj4513储能表&bzoj4514数字配对 已写 ...

  6. 20175221 《Java程序设计》迭代和JDB(课下作业,选做):

    20175221 <Java程序设计> 迭代和JDB(课下作业,选做): 任务详情 1 使用C(n,m)=C(n-1,m-1)+C(n-1,m)公式进行递归编程实现求组合数C(m,n)的功 ...

  7. MyOD(课下作业,选做)

    MyOD(课下作业,选做) 代码要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.b ...

  8. 迭代和JDB(课下作业,选做)

    迭代和JDB(课下作业,选做) 题目要求 1 使用C(n,m)=C(n-1,m-1)+C(n-1,m)公式进行递归编程实现求组合数C(m,n)的功能 2 m,n 要通过命令行传入 3 提交测试运行截图 ...

  9. 20175312 2018-2019-2 《Java程序设计》第6周课下选做——类定义

    20175312 2018-2019-2 <Java程序设计>第6周课下选做--类定义 设计思路 1.我觉得Book其实就是一个中转的作用,由测试类Bookself通过Book输入数据,然 ...

随机推荐

  1. SEC5 - MySQL 查询语句--------------进阶1:基础查询

    # 进阶1:基础查询 /* 语法: select 查询列表 from 表名: 特点: 1.查询列表可以是:表中的字段.常量值.表达式.表达式.函数 2.查询的结果是一个虚拟的表格 如何执行:执行谁,请 ...

  2. Winsows10-1909正式版原版下载资料

    [简体中文版] 一.win10 1909消费者版(零售版),含家庭版.家庭单语言版.教育版.专业版.专业教育版.专业工作站版 (6个版本) 1.64位系统:Windows 10 (consumer e ...

  3. 20190823 尚硅谷MySQL核心技术

    背景 视频时间:2017.09 MySQL版本:5.5 MySQL基础 命令行启动.停止MySQL: net start MySQL(这里是注册的服务名称) net stop MySQL 命令行连接M ...

  4. 继承Process类,计算累加和以及阶乘

    #定义一个类 继承Process类 from multiprocessing import Process import os class Download(Process): def __init_ ...

  5. python学习那点事---pycharm使用弹框问题如何解决

    学习python的目标:年后可以找一份不错的维护工作. 2019.11.4日是第一天开始学习python,从开始安装python3.6版本和pycharm开始.安装python版本非常顺利的就完成了, ...

  6. 【转载】ROS系统整体架构

    目录 1.从文件系统级理解 2.从计算图级理解 3.从开源社区级理解 由于ROS系统的组织架构比较复杂,简单从一个方面来说明很难说清楚.按照ROS官方的说法,我们可以从3个方面来理解ROS系统整体架构 ...

  7. JavaWeb——servlet1

    一.servlet简介 Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于 ...

  8. ubuntu离线安装mysql

    一:ubuntu离线安装mysql 转载来源:https://blog.csdn.net/liuhuoxingkong/article/details/80696574 参考文章:https://ww ...

  9. [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)

    [Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...

  10. Cannot modify header information - headers already sent by出错的原因

    <?php ob_start(); setcookie("username","送家",time()+3600); echo "the user ...