2017-2018-1 20155326 《信息安全系统设计基础》第四周学习总结及myod改进版的补交

学习内容

  • 补充完成课上没有完成的内容

  • 学习教材附录A,第十章内容

  • 参考别出心裁的Linux系统调用学习法,学习视频,掌握两个重要命令:

    • man -k key1 | grep key2| grep 2 : 根据关键字检索系统调用

    • grep -nr XXX /usr/include :查找宏定义,类型定义

  • 完成head,tail的使用,相关API的分析,伪代码,产品代码,测试代码的编写(3分)

别出心裁的Linux系统调用学习法学习总结

输入 man -k system |grep call 得到调用的相关信息。

由图可知我们应该先查看intro 输入 man 2 intro。

得到system calls的介绍后,提示我们找syscalls(2)。输入man 2 syscalls 查看Linux kernel的系统调用。

在娄老师发的教程指导学习中,我们通过三个步骤来学习:

  • 首先分析程序

分析一个东西首先要了解它的功能,使用cheat命令可以通过一个个的例子展示命令的功能。由于我的虚拟机没有安装Python,cheat,所以我首先进行了安装。

安装完cheat后我们可以输入 cheat find 来得到find的功能例子。

我们想要分析who的用法,于是我们输入cheat who 来更好的理解who命令,遗憾的是并没有who的例子说明,于是我们转而输入man who 来查看who命令的功能。

根据帮助文档我们知道了who命令的功能是输出登录信息:登录者的姓名、机器名称和登录时间。

  • 之后我们学习它的系统调用

在下图中,我们得知存在一个/var/run/utmp文件,这个文件保存当前用户的登录信息。

我们进一步分析/var/run/utmp,输入 cat /var/run/utmp查看里面的信息,由此我们可以得知这是一个二进制文件,可以通过od -tx1 /var/run/utmp 来查看其中内容。

接着我们使用man -k查看我们需要找的utmp的属性信息,找到了要找的utmp(5)。

输入man 5 utmp 查看帮助手册,在帮助手册中我们看到了实现utmp功能的代码,其中有两个结构体功能,用于记录登陆信息。这下我们知道了who功能的实现是依靠读取utmp文件中的信息。

使用grep -nr "struct utmp" /usr/include来查找struct utmp在哪个头文件中被定义。查找结果如下:

  • 最后进行编程实现

利用学到的原理和系统调用,自己编程实现原来程序所实现的功能。

编写代码的三部曲是:

1) 伪代码:

	打开utmp文件
循环读每一条记录
打印用户名、终端和时间
关闭utmp文件,结束 2)产品代码 3) 测试代码

教材学习中遇到的问题

运行书上代码时发现问题。见下图:

参考网址https://group.cnblogs.com/topic/73278.html后我得知,这是作者自己写的一个头文件,需要拷到电脑里。

然后发现放的地方不对,要放在usr/lib里。放的时候不能直接放,需要用命令行将csapp.c/.h复制到lib。参考网址http://www.linuxidc.com/Linux/2008-11/17179.htm

移进后仍然错误

将.c.h文件放到lib以后还是不行

移到include以后也不对。

head的实现

  • 首先分析head

由此大概可知head的功能是显示一个文件前十行的内容。

再接着查看帮助手册,进一步确定了它的功能。

  • 系统调用

由于这个命令较简单我们并不需要学习系统调用便可直接实现他的功能。

  • 最后进行编程实现

    1. 伪代码:

      打开自定义(lmc.txt)文件

      循环打印出每行内容直至第十行

      关闭文件,结束

    2)产品代码

      filename=argv[1];
    rfd=open(argv[1],O_RDONLY,0);
    if((rlen=read(rfd,rbuf,READSIZE))>0)
    {
    for(i=0;i<rlen;i++)
    {
    if(rbuf[i]=='\n')
    {
    pb=&rbuf[i];
    if(++nent==10)
    break;
    }
    }
    }
    close(rfd);
    for(j=0;j<=i;j++)
    { printf("%c",rbuf[j]);
    }
    }
    }
  • head编译过程中遇到的问题

最开始我编译运行时,没有任何返回的值,为了查看错误出在哪里,我在for循环出设置了printf来查看循环是否起作用。

这样看来循环是正确的。

于是我在每个if、循环处都设置了printf,从变量的值来查看哪个模块出了问题。

从图中看那些变量都没问题,每个模块都正常,唯独最后一行显示4196719。查看代码得出这是printf("%s",rbuf);的结果,然而我需要输出的是后十行内容,这样明显是错误的。

将输出换成一个for循环后运行终于正确了。

(head码云链接)[https://gitee.com/lmc1998/lmc20155326/tree/master/src/week4]

tail的实现

  • 首先分析tail

由此大概可知tail的功能和head相反,是显示一个文件后十行的内容。

再接着查看帮助手册,确定它的功能。

  • 系统调用

由于这个命令较简单我们并不需要学习系统调用便可直接实现他的功能。

  • 最后进行编程实现

    1. 伪代码:

      打开自定义(lmc.txt)文件

      找到文件后十行

      循环打印出每行内容直至结束

      关闭文件,结束

    2)产品代码

tail代码和head差不多,只是改了循环中的内容。

int main(int argc,char *argv[]){
int rlen=0; //wenjianneirongchangdu
int nline=10; //duquwenjianhangshu
int nent=0; //jishuqi
int rfd; //wenjianmiaoshufu
int i,j,m;
char rbuf[READSIZE]; //duquwenjianhuancunqu
char *filename;
char *pb=0; //zhixiangmeihanghuanhang
memset(rbuf,0,READSIZE);
filename=argv[1];
rfd=open(argv[1],O_RDONLY,0);
if((rlen=read(rfd,rbuf,READSIZE))>0)
{
for(i=0;i<rlen;i++)
{
if(rbuf[i]=='\n')
{
pb=&rbuf[i];
nent++;
if(++nent==10)
m=i;
}
}
close(rfd);
for(j=m;j<=rlen;j++)
{ printf("%c",rbuf[j]);
}
}
}
  • tail编译过程中遇到的问题

才开始的时候,我想当然的将第二个for循环的f=i换成了i-10。运行出来结果如下:

仔细思考过后我发现我太蠢了,j怎么能从i-10开始呢,rbuf[]是个字符串数组,储存打开的文件的所有内容。应该是从最后十行的开始的i开始输出。于是定义了一个新的变量m记录最后十行开始的i的值。

	for(i=0;i<rlen;i++)
{
if(rbuf[i]=='\n')
{
pb=&rbuf[i];
nent++;
// if((read(rfd)
if(++nent==10)
m=i;
// break; }
}
close(rfd);
for(j=m;j<=rlen;j++)
{ printf("%c",rbuf[j]);
}

编译成功图片

(tail码云链接)[https://gitee.com/lmc1998/lmc20155326/tree/master/src/week4]

myod改进版

题目

1 参考教材第十章内容

2 用Linux IO相关系统调用编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能,注意XXX是文件名,通过命令行传入,不要让用户输入文件名

3 不要把代码都写入main函数中

4 要分模块,不要把代码都写入一个.c中

实践过程:

这次主要运用了第十章的知识,根据题目,可以得知需要myod1.0版本改进的地方分别是:

  • 将主函数改为调用参数形式,即int main(int argc,char * argv[]), 其中argc是命令行总的参数个数 , * argv[]:是字符串数组,用来存放指向你的字符串参数的指针数组,每一个元素指向一个参数。

    argv[0]:指向程序的全路径名

    argv[1]:指向在DOS命令行中执行程序名后的第一个字符串。

    argv[2]:指向第二个字符串,以此类推。

  • 由于文件名从命令行获得,所以不用在程序中输入文件名啦,去掉*fp 文件指针。

  • 根据第十章内容,open函数是linux中非常方便的按照给定路径打开文件的函数。可建立一个整型变量用于取得文件打开后的返回值,即int fd。以只读方式打开已存在文件则有fd=open(argv[1],O_RDONLY),当open()返回值为-1时打开文件失败。close()函数关闭文件即可。

  • 接着对头文件进行修改

代码修改如下图:

对代码的修改基本都在主函数部分。

运行结果如下:

myod码云链接

总结

这次学习了第十章的内容,对I/O有了更深的理解。也知道了原来自己也可以编写linux里面的命令。但是觉得自己能力还是太弱,一步步加强吧。

2017-2018-1 20155326 《信息安全系统设计基础》第四周学习总结及myod改进版的补交的更多相关文章

  1. 2017-2018-1 20155326信息安全系统设计基础》嵌入式C语言课上考试补交

    2017-2018-1 20155326信息安全系统设计基础>嵌入式C语言课上考试补交 PPT上的例子 已知位运算规则为: &0 --> 清零 &1 --> 不变 | ...

  2. 20135328信息安全系统设计基础第一周学习总结(Linux应用)

    学习计时:共xxx小时 读书: 代码: 作业: 博客: 一.学习目标 1. 能够独立安装Linux操作系统   2. 能够熟练使用Linux系统的基本命令   3. 熟练使用Linux中用户管理命令/ ...

  3. 20135328信息安全系统设计基础第二周学习总结(vim、gcc、gdb)

    第三周学习笔记 学习计时:共8小时 读书:1 代码:5 作业:1 博客:7 一.学习目标 熟悉Linux系统下的开发环境 熟悉vi的基本操作 熟悉gcc编译器的基本原理 熟练使用gcc编译器的常用选项 ...

  4. # 20155337 2017-2018-1 《信息安全系统设计基础》第二周课堂实践+myod

    20155337 2017-2018-1 <信息安全系统设计基础>第二周课堂实践+myod 因为在课上已经提交了四个实验,还欠缺最后一个实验,反省一下自己还是操作不熟练,平时在课下应该多多 ...

  5. LINUX信息安全系统设计基础第一周学习总结

     Linux系统简介 一.实验内容 了解 Linux 的历史,Linux 与 Windows 的区别等入门知识. 二.实验要求 阅读linux简介与历史 三.实验步骤 二.Linux 与 Window ...

  6. LINUX信息安全系统设计基础第二周学习总结

    1 Linux命令 2 man命令 1.Terminal(终端) Linux 系统还提供了一个叫做终端模拟器的程序(Terminal),下面几个比较常见的终端模拟器,例如 gnome-terminal ...

  7. 20155326 2017-2018-1 《信息安全系统设计基础》课下加分项mypwd实现

    20155326 2017-2018-1 <信息安全系统设计基础>课下加分项mypwd实现 pwd命令能做什么 在虚拟机中输入pwd查看其返回的是什么 通过上图得知pwd命令用来显示目录. ...

  8. 20155326 2017-2018-1 《信息安全系统设计基础》第2周学习及课堂总结myod

    20155326 2017-2018-1 <信息安全系统设计基础>第1次学习及课堂总结myod 虚拟机之前出了一些问题,然后我重新弄了一个新的虚拟机. 先在虚拟机里面安装了git. 安完以 ...

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

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

随机推荐

  1. 关于java.io.IOException: HADOOP_HOME or hadoop.home.dir are not set.的问题

    报错如下: 300 [main] DEBUG org.apache.hadoop.util.Shell - Failed to detect a valid hadoop home directory ...

  2. eclipse中增加多个Tomcat

    一.在eclipse中新增Tomcat,并增加在其上部署的工程 1.打开eclipse,并选择菜单中的 "Window" ---> "Show View" ...

  3. CF Round #510 (Div. 2)

    前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了..最后才\(A\)了\(3\) ...

  4. CButtonST|CUniButton等按钮类的使用

    CButtonST CButtonST类的使用参考链接:http://www.cnblogs.com/lidabo/archive/2012/12/17/2821122.html CCeButtonS ...

  5. POJ1659 Frogs' Neighborhood(青蛙的邻居) Havel-Hakimi定理

    Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 8729   Accepted: 36 ...

  6. spring boot 启动自动跳到 断点 throw new SilentExitException

    项目 debug 启动,自动跳到 断点 ,而且就算F8 ,项目还是停止启动. 百度了一下,答案都是 Eclipse -> Preferences ->Java ->Debug去掉&q ...

  7. ros 编程习惯

    1.设置ros的info,warning,debug,error等编写的时候要思考,何时该使用,以及在开头要使用设置rosconsole的级别来对应输出,以方便调试. 2.在使用ros_info等的时 ...

  8. m序列c语言实现

    演示,不是算法 void m4() { int a[4]={1,0,0,1}; int m[15]; int temp; for(int i=0;i<15;i++){ m[i] = a[0]; ...

  9. 转载 html div三列布局占满全屏(左右两列定宽或者百分比、中间自动适应,div在父div中居底)

    原文地址:http://blog.csdn.net/duyelang/article/details/20558899 <p><!DOCTYPE html> <html ...

  10. 18 包 ,logging模块使用

    包: 1 什么是包: 包就是一个包含有__init__.py文件的文件夹 宝本质就是一种模块,即包就是用包导入使用的,包内部包含的文件也都是用来被导入使用 2 为什么要用包 包就是文件夹,那文件加就是 ...