2017-2018-1 20155214 《信息安全系统设计基础》第四周学习总结

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:1071line: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]=='\n')
 40             {printf("%5s","\\n");continue;}
 41         if(line[i]=='\t')
 42             {printf("%5s","\\t");continue;}
 43             putchar(line[i]);
 44             printf("    ");
 45         }
 46         putchar('\n');
 47         }
            ……

结果运行截图

myod代码码云链接

关于head和tail

  • head

输出文件的第一部分,打印文件前10行到标准输出中

可以在coreutils包中找到源码。

myhead代码

设计思路

  • 通过count计算回车符‘\n’个数,当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!\n");exit(1);}

    while(read(fd,&ch,1)!=0)
    {
        putchar(ch); 
        if(ch == '\n'){count++;}
        if(count == 10){break;}
    }

    close(fd);

    return 0;
}
  • tail

输出文件的最后一部分,打印最后10行到标准输出中。

与head有联系,也在coreutils包中

学习的思考和感悟

通过本次课后练习加深了对系统调用的理解,尝试阅读了系统内的源码后,发现了自己的c语言功底还不够扎实,函数模块彼此的独立性做的还不够。

posted @ 2017-10-13 11:14  曾士轩  阅读(483)  评论(2编辑  收藏  举报