实现cp命令

106 阅读1分钟

cp命令

cp source target 将source复制到target

实现思路

  1. 打开source文件 打开target文件
  2. 将source文件内容读取到buffer缓冲区中
  3. 判断是否到文件结尾
  4. 将buffer缓冲区数据写入到target文件
  5. 关闭source文件和target文件

代码

// cp.h
#ifndef MYCP_H__
#define MYCP_H__

#define FILEMODE 0644
#define BUFFERSIZE 4096

void print_err(char *msg, char *sys_msg);
int cp(char *source, char *target);

#endif
// cp.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

void print_err(char *msg, char *sys_msg) {
    fprintf(stderr, "Error: %s ", msg);
    perror(sys_msg);
}

int cp(char *source, char *target) {
    int source_fd,target_fd,num_of_bytes;
    char buffer[BUFFERSIZE];
    
    source_fd = open(source, O_RDONLY);
    if(source_fd == -1) {
        print_err("open failed ", source);
        return -1;
    }
    
    target_fd = creat(target, FILEMODE);
    if(target_fd == -1) {
        print_err("create failed ", target);
        return -2;
    }
    
    while((num_of_types = read(source_fd, buffer, BUFFERSIZE)) > 0) {
        if(write(target_fd, buffer, num_of_types) != num_of_types) {
            print_err("write error ", target);
            return -3;
        }
    }
    
    if(num_of_types == -1) {
        print_err("read error ", source);
        return -4;
    }
    
    if(close(source) == -1 || close(target) == -1) {
        print_err("close failed ", "");
        return -5;
    }
    
    return 0;
}
// main.c
#include <stdio.h>
#include <stdlib.h>
#include "cp.h"

int main(int argc, char *argv[]) {
    if(argc < 3) {
        fprintf(stderr, "Usage: %s <source> <target>.\n", argv[0]);
        exit(1);
    }
    
    if(cp(argv[1], argv[2]) < 0)
        exit(1);
    
    exit(0);
}

内核缓冲

将磁盘上的数据复制到内核缓冲区

graph TD
进程要求的数据块不在内核缓冲区 --> 内核把数据块加入请求数据列表 --> 挂起该进程 --> 内核把请求的数据块从磁盘读入内核缓冲区 --> 把数据复制到进程缓冲区 --> 唤醒进程

read函数:将数据从内核缓冲区读到进程缓冲区
write函数:将数据从进程缓冲区写入内核缓冲区
如果写入磁盘前断电会导致内核中数据丢失