2017-2018-1 20155214 《信息安全系统设计基础》第四周学习总结
课后练习 —— myod-系统调用版本(linux)
题目要求
- 参考教材《深入理解计算机(第三版)》第十章内容
- 用Linux IO相关系统调用编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能,注意XXX是文件名,通过命令行传入,不要让用户输入文件名
- 不要把代码都写入main函数中
- 要分模块,不要把代码都写入一个.c中
- 提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息
题目背景
关于od及其源码
- od是linux下常用的命令行,通过
man od
查看它的相关信息
- 由此可知,od作为命令行,源码在包
coreutils
中,通过locate coreutils
定位。
-
发现本地只有一个
libstdbuf.so
的共享库,没有源代码。 -
在网站GNU Operating System[http://www.gnu.org/software/coreutils/coreutils.html]中找到了资源,打开压缩包,在coreutils/src下发现了od.c
-
在vim中输入
/fread
高亮显示匹配,发现od.c分别在line:1071
和line:1297
读入文件
-
而line:1297中的函数read_block只在函数dump函数中被调用过,dump函数应是较中心的函数,其中write_block为输出函数。
-
在vim中输入
/switch
高亮显示匹配,可以找到其他匹配系数的主要的函数 -
根据对od源代码的阅读可以让我们在编写myod时有迹可循。
myod代码结构
主要函数
-
read_block
从文件中按字符读取 -
通过在read_block中调用系统I/0,
read(fd,&ch,1)
循环读取字符。
12 void read_block(int fd,char line[16],int n[4])
13 {
14 int LINE_NUM=0;
15 int BIT=0;
16 char ch;
17
18 while(read(fd,&ch,1)!=0)
19 {
20 line[BIT%16] = ch;
21 if((BIT+1)%16==0)
22 {
23 write_block(line,n,LINE_NUM);
24 LINE_NUM++;
25 }
26 BIT++;
27 }
28
29 }
-
write_block
按od规则按字符输出。 -
读入16个字符的数组line后,按照参数数组n选择输出格式。
31 void write_block(char line[16],int n[4],int LINE_NUM)
32 {
33 int i;
34
35 printf("%07o ",16*LINE_NUM);
36
37 if(n[0]){for(i=0;i<16;i++)
38 {
39 if(line[i]=='
')
40 {printf("%5s","\n");continue;}
41 if(line[i]==' ')
42 {printf("%5s","\t");continue;}
43 putchar(line[i]);
44 printf(" ");
45 }
46 putchar('
');
47 }
……
结果运行截图
myod代码码云链接
关于head和tail
- head
输出文件的第一部分,打印文件前10行到标准输出中
可以在coreutils包中找到源码。
myhead代码
设计思路
-
通过count计算回车符‘ ’个数,当count==10时,停止输出。
-
伪代码
int main()
{
……
计数标志 count=0;
循环按字符读入文件
{
输出字符;
if(读入字符为回车符){cout++;}
if(count==0){退出循环}
}
……
}
- 产品代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
int count=0;
char ch;
int fd=0;
fd=open(argv[argc-1],O_RDONLY,0);
if(fd==-1){printf("Error!
");exit(1);}
while(read(fd,&ch,1)!=0)
{
putchar(ch);
if(ch == '
'){count++;}
if(count == 10){break;}
}
close(fd);
return 0;
}
- tail
输出文件的最后一部分,打印最后10行到标准输出中。
与head有联系,也在coreutils包中
学习的思考和感悟
通过本次课后练习加深了对系统调用的理解,尝试阅读了系统内的源码后,发现了自己的c语言功底还不够扎实,函数模块彼此的独立性做的还不够。