当前位置: 首页 > 工具软件 > MYCP > 使用案例 >

文件读写 | mycp.c 将源文件复制到目标文件

阮喜
2023-12-01

1.题目要求

  • mycp.c的功能与系统cp程序相同

  • 将源文件复制到目标文件,例子如下:

  • 要求使用系统调用open/read/write/close实现

    $ cat /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    ...
    $ ./mycp /etc/passwd passwd.bak 
    $ cat passwd.bak
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    ...
    

2.解决思路

​ 程序需要接收命令行参数,argv[1]argv[2]分别是原文件与待复制文件的文件路径。首先打开原文件,读取文件中的数据到内存缓冲区,关闭文件。然后打开待复制的文件(若不存在则创建,若已存在则将文件长度截断为0),将内存缓冲区的内容写入到该文件中,关闭文件。在打开文件、读取文件、写入文件时,若系统调用失败,调用panic子函数打印报错信息并终止程序。

3.代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

// 定义内存缓冲区大小
#define MAXSIZE 65536 

// 当系统调用失败时,调用panic函数终止程序
// perror打印系统调用的报错信息
void panic(char *message) {
  perror(message);
  exit(EXIT_FAILURE);
}


int main(int argc, char *argv[]) {
  char *path = argv[1];
  char *cp_path = argv[2];
  char buffer[MAXSIZE];

  // 打开原文件,读取文件中的数据到内存缓冲区,关闭文件
  int fd = open(path, O_RDONLY);
  if(fd < 0) 
    panic("open");
  
  int count = read(fd, buffer, sizeof(buffer));
  if(count < 0) 
    panic("read");
  
  close(fd);

  // 打开待复制的文件(若不存在则创建),将内存缓冲区的内容写入到文件中,关闭文件
  int fd_cp = open(cp_path, O_CREAT|O_WRONLY|O_TRUNC);
  if(fd_cp < 0)
    panic("open");
  
  int count_cp = write(fd_cp, buffer, count);
  if(count_cp < 0)
    panic("write");
  
  close(fd_cp);

  return 0;
}

4.运行结果

需要注意的是cat passwd.bak命令需要在root权限下执行

$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...

$ gcc mycp.c -o mycp
$ ./mycp /etc/passwd passwd.bak 
$ cat passwd.bak
cat: passwd.bak: 权限不够
$ sudo cat passwd.bak
[sudo] (用户名XXX) 的密码: 
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
 类似资料: