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


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

    课上实践--myod-系统调用版本

    • 要求:

      1.参考教材第十章内容
      2.用Linux IO相关系统调用编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能,注意XXX是文件名,通过命令行传入,不要让用户输入文件名
      3.不要把代码都写入main函数中
      4.要分模块,不要把代码都写入一个.c中
      5.提交测试代码和运行结果截图,提交调试过程截图,要全屏,包含自己的学号信息
      6.课上上传代码到码云
      

    head,tail的相关学习

    相关API的分析

    • head
      • 语法:head [参数] 文件
      • 命令功能:head用来显示档案的开头至标准输出当中,默认head命令打印其相应文件的开头10行。

     -c<字符数>:指定显示头部内容的字符数
    -n<数字>:指定显示头部内容的行数
    

    来自: http://man.linuxde.net/head

    • tail
      • 功能:显示指定文件的后若干行。
      • 语法: tail [+ / - num ] [参数] 文件
      • tail命令中各个选项的含义为:+num 从第num行以后开始显示。-num 从距文件尾 num行处开始显示。如果省略 num参数,系统默认值为 10。

    • 使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不但刷新,使你看到最新的文件内容。

    伪代码,产品代码,测试代码的编写

    • myhead

    伪代码:

    打开文件;
    循环按字符读入文件,每读一个换行符计数器加一;
    读满10个换行符停止输出;
    结束程序
    

    产品代码:

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc,char *argv[])
    {
    
        int fd,c=0;
        char ch;
        fd=open(argv[1],O_RDONLY,0);
        if(fd==-1)
        {
            printf("出现错误!");
            exit(1);
        }
        while(read(fd,&ch,1)!=0)
        {
            printf("%c",ch);
            if(ch=='
    ') c++;
            if(c==10) break;
        }//方法参考p599图10-2程序,将while循环中的write(fd,&ch,1)改为从屏幕输出字符,并加入了判断。
        close(fd);
        exit(0);
    }
    

    • tail

    伪代码:

    打开文件;
    循环按字符第一次读入文件,统计总共的行数;
    再次读入文件,当行数>=总行数-10时输出字符;
    结束程序
    

    产品代码:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    int main(int argc,char *argv[])
    {
    
        int fd1,fd2,c=0,n=0;
        char ch;
    
        fd1=open(argv[1],O_RDONLY,0);
        if(fd1==-1)
        {
            printf("出现错误!");
            exit(1);
        }
        while(read(fd1,&ch,1)!=0)
          {
              if(ch=='
    ') c++;
           }
        close(fd1);
    
        fd2=open(argv[1],O_RDONLY,0);
        while(read(fd2,&ch,1)!=0)
          {
              if(ch=='
    ') n++;
              if(n>=c-10)printf("%c",ch);
           }
    
        close(fd2);
        exit(0);
    }
    

    教材学习中的问题和解决过程

    • 问题1:练习题10.1程序的输出为什么是3?即打开文件和文件描述符的关系是什么?

    • 问题1解决方案:

      查阅资料后有段话解释了我的问题:

    在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件、目录文件、链接文件和设备文件。文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。如果此时去打开一个新的文件,它的文件描述符会是3,再调用open 就会返回4。

    而且我了解到

    每个进程在Linux内核中都有一个task_struct结构体来维护进程相关的 信息,称为进程描述符(Process Descriptor),而在操作系统理论中称为进程控制块 (PCB,Process Control Block)。task_struct中有一个指针(struct files_struct *files; )指向files_struct结构体,称为文件 描述符表,其中每个表项包含一个指向已打开的文件的指针,如下图所示。

    用户程序不能直接访问内核中的文件描述符表,而只能使用文件描述符表的索引 (即0、1、2、3这些数字),这些索引就称为文件描述符(File Descriptor),用int 型变量保存。 当调用open 打开一个文件或创建一个新文件时,内核分配一个文件描述符并返回给用户程序,该文件描述符表项中的指针指向新打开的文件。当读写文件时,用户程序把文件描述符传给read 或write ,内核根据文件描述符找到相应的表项,再通过表项中的指针找到相应的文件。

    这就加深了我对打开文件和文件描述符的理解,也知道了家庭作业10.6的答案:因为调用了两次open函数,所以返回值是4,然后调用close释放了描述符4,再次调用open返回值又是4了,所以输出是4。

    自己敲代码验证了一下:

    代码学习中的问题和解决过程

    • 问题1:运行程序时遇到了头文件csapp.h错误的情况
    • 问题1解决方案:csapp.h其实就是一堆头文件的打包,在http://csapp.cs.cmu.edu/public/code.html 这里可以下载。《深入理解计算机系统》配套网站
      下载并解压后(以 root 身份登录)应该是一个code的文件夹,在其子文件夹include和src中分别可以找到csapp.h和csapp.c两个文件,把这两个文件拷贝到文件夹/usr/include里面,并在csapp.h文件中 #endif 之前加上一句 #include<csapp.h> ,然后编译时在最后加上 “-lpthread” 例如:gcc main.c -lpthread 就可以编译了。

    代码链接

    参考资料

  • 相关阅读:
    java 将表情转换成字符串存入数据库
    java html websocket简单实现
    Java poi读取Excel表格中公式的计算值
    转盘代码,自己搞了一个
    html5 canvas画布
    cat命令查看文件指定行数
    CentOS7 安装 gpbackup 和 gpbackup-s3-plugin 来备份和还原 Greenplum 数据库
    QT5 打包发布Release应用程序
    CentOS7 安装Redis6.0.10
    ES系列(二):基于多播的集群发现实现原理解析
  • 原文地址:https://www.cnblogs.com/haoliberale/p/7674592.html
Copyright © 2020-2023  润新知