C语言编写Copy程序(Linux环境下的操作)

版权声明:[email protected] https://blog.csdn.net/Baron_wu/article/details/83147817

COPY程序的编写

(作者:Baron_wu 禁止转载)

一、实验描述

在这个实验中,我们要做一个程序,这个程序是将一个文件的内容复制到一个目标文件。首先这个程序提示用户输入要复制的原始文件的名字,以及要复制到的目标文件的名字。
确保包括必要的错误检查,包括确保原始文件存在。再使用程序的同时我们要监视这个过程中所用到的系统调用。Linux可使用strace来完成。

二、相关原理与知识

(完成实验所用到的相关原理与知识)
系统调用的工作方式:
一般的,进程是不能访问内核的。它不能访问内核所占内存空间也不能调用内核函数。CPU硬件决定了这些(这就是为什么它被称作"保护模式")。系统调用是这些规则的一个例外。其原理是进程先用适当的值填充寄存器,然后调用一个特殊的指令,这个指令会跳到一个事先定义的内核中的一个位置(当然,这个位置是用户进程可读但是不可写的)。在Intel CPU中,这个由中断0x80实现。硬件知道一旦你跳到这个位置,你就不是在限制模式下运行的用户,而是作为操作系统的内核–所以你就可以为所欲为。
进程可以跳转到的内核位置叫做sysem_call。这个过程检查系统调用号,这个号码告诉内核进程请求哪种服务。然后,它查看系统调用表(sys_call_table)找到所调用的内核函数入口地址。接着,就调用函数,等返回后,做一些系统检查,最后返回到进程(或到其他进程,如果这个进程时间用尽)。如果你希望读这段代码,它在==<内核源码目录>/kernel/entry.S,Entry(system_call)==的下一行。

图为运行过程中用户模式到内核模式的一个open函数的调用。
在这里插入图片描述

图为参数存在内存的图和表中,并将块的地址通过寄存器来传递。
在这里插入图片描述

图为c程序在调用printf时,c程序库拦截这个调用来调用必要的操作系统调用write()。然后c程序再将write的返回值返回给用户。
在这里插入图片描述

三、实验过程

(实际操作过程,相关截图及解释)

  1. 创建一个copy.c文件,写入代码
    在这里插入图片描述
    在这里插入图片描述

  2. 写入的复制文件的代码(一种方式为用户在执行程序时就传入参数,另一种方式为交互式让用户输入参数<注释掉的代码>。)

  3. 编译写好的copy.c文件
    在这里插入图片描述

  • strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。-o
    xxx.txt 输出到某个文件。./copy即为运行copy。
    在这里插入图片描述

查看复制后的文件的内容
在这里插入图片描述

  • 利用ls查看所有生成的文件,即由strace生成的copy.txt文件以及复制后得到的copy1.c文件
    在这里插入图片描述
  • 查看生成的copy.txt文件的内容

在这里插入图片描述
在这里插入图片描述

  • 输入strace -c ./copy来获取复制过程中所调用的系统函数,可以看到此过程中调用的read、write、open、close…等函数。
    在这里插入图片描述
  • 实验分析:根据指令strace -c ./copy可以看到在文件复制过程中使用了文件系统控制系统调用。
read:读文件
write:写文件
open:打开文件
close:关闭文件描述字
fstat:取文件状态信息
lseek:移动文件指针
mmap:映射虚拟内存页
mprotect:设置内存映像保护
munmap:去除内存页映射
brk:改变数据段空间的分配
access:确定文件的可存取性
execve:运行可执行文件
arch_prctl:  函数设置架构的具体进程或线程状态

源代码

(源程序)c程序源代码


    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    int main(int argc,char *argv[])
    {
        FILE * fin;
        FILE * fout;
        int ch;
        char *f_read = argv[1];
        char *f_write = argv[2];
        // printf("input the file :");
        // scanf("%s",f_read);
        // printf("input the new file name :");
        // scanf("%s",f_write);
        
        fin = fopen(f_read,"rb");
        fout = fopen(f_write,"wb");
        ch = getc(fin);
        while(ch != EOF)
        {
          putc(ch,fout);
          ch = getc(fin);
        }
        return 0;
        
    }

执行程序的指令:

  1. vim copy.c打开copy.c并进行编辑
  2. gcc -o copy copy.c编译copy.c生成copy程序
  3. ./copy执行copy程序
  4. cat copy1.c查看复制后的文件copy.txt的内容
  5. strace -o copy.txt ./copy监视copy程序的执行,并生成一个copy.txt监视文件
  6. strace -c ./copy查看执行copy程序时调用了那些系统调用

猜你喜欢

转载自blog.csdn.net/Baron_wu/article/details/83147817