使用 linux 上的系统调用将目录文件复制到另一个目录

Copy files of directory into another using system calls on linux

我正在尝试使用系统调用将文件从一个目录复制到另一个目录,但我收到“违反段核心”的消息,我不知道为什么,第一个参数是原始目录,第二个是目标目录,第三个未使用,第四个是我开始复制第一个目录的每个文件的字节位置我的意思是例如如果 Pos = 4 并且文件是 hello 复制的文件内容将是 o 因为我使用 lseek移动到位置 4 的指针并从那里开始复制,这是我的代码:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#define BS 512
#define error(a) {perror(a); exit(1);};

int main(int argc, char *argv[]) //argv1 Dir1 argv2 Dir2 argv3 Fich argv4 Pos
{
    DIR *dir1;
    DIR *dir2;
    struct dirent *lectura1;
    struct dirent *lectura2;
    struct stat st;
    int datos1;
    int datos2;
    int size;
    char path[256] = "";
    char path2[256] = "";
    char temp[256];
    char buf[BS];
    int j;
    int i;
    if(argc != 5)
    {
       error("Numero de argumentos incorrecto");
    }
    int Pos = atoi(argv[4]);
    if(Pos < 0)
    {
        error("Pos must be 0 or greater")
    }
    
    if((dir1 = opendir(argv[1])) == NULL){error("Failed to open origin dir");}
    if((dir2 = opendir(argv[2])) == NULL){error("Failed to open destiny dir");}
    
    while((lectura1 = readdir(dir1)) != NULL)
    {
        sprintf(path, "%s/%s", argv[1], lectura1->d_name);
        lectura2 = readdir(dir2);
        sprintf(path2, "%s/%s", argv[2], lectura2->d_name);
        
        if (strcmp(lectura1->d_name, "..") != 0 && strcmp(lectura1->d_name, ".") != 0) 
        {
            if (stat(path, &st) == 0) 
            {
                if (S_ISREG(st.st_mode)) //If is a regular file 
                {
                    if((datos1 = open(path, O_RDONLY, 00600)) == -1){error("Failed to open file");} //Opens the target file of Dir1 to copy inside Dir2
                    size = lseek(datos1,0,SEEK_END);
                    if (size > Pos) //Check if the size of the file is bigger than the position that indicates the point from which to start copying the file
                    {
                        lseek(datos1,Pos,SEEK_SET); //Moves the pointer to the start position of the file1
                        if((datos2 = open(path2, O_CREAT|O_WRONLY, 00200)) == -1){error("Error al abrir archivo copia");}
                        lseek(datos2,0,SEEK_SET);
                        j = BS;
                        i = 0;
                        int n = 0;
                        if ((size - i) < BS) 
                        {
                            j = size - i;
                        }
                        while ((n = read(datos1, buf, BS)) > 0) 
                        {
                            n = write(datos2, buf, j);
                            i = i + n;
                            if ((size - i) < BS) 
                            {
                                j = size - i;
                            }
                        }
                        close(datos1);
                        close(datos2);
                    }    
                }        
            }    
        }           
    }
    close(dir1);
    close(dir2);
    return 0;
}

是的,它似乎是这样工作的:

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#define BS 512
#define error(a) {perror(a); exit(1);};

int main(int argc, char *argv[]) //argv1 Dir1 argv2 Dir2 argv3 Fich argv4 Pos
{
    DIR *dir1;
    DIR *dir2;
    struct dirent *lectura1;
    struct dirent *lectura2;
    struct stat st;
    int datos1;
    int datos2;
    int size;
    char path[256] = "";
    char path2[256] = "";
    char temp[256];
    char buf[BS];
    int j;
    int i;
    if(argc != 5)
    {
       error("Numero de argumentos incorrecto");
    }
    int Pos = atoi(argv[4]);
    if(Pos < 0)
    {
        error("Pos must be 0 or greater")
    }

    if((dir1 = opendir(argv[1])) == NULL){error("Failed to open origin dir");}
    if((dir2 = opendir(argv[2])) == NULL){error("Failed to open destiny dir");}

    while((lectura1 = readdir(dir1)) != NULL)
    {
        sprintf(path, "%s/%s", argv[1], lectura1->d_name);
        sprintf(path2, "%s/%s", argv[2], lectura1->d_name); //<-- changed param

        if (strcmp(lectura1->d_name, "..") != 0 && strcmp(lectura1->d_name, ".") != 0)
        {
            if (stat(path, &st) == 0)
            {
                if (S_ISREG(st.st_mode)) //If is a regular file
                {
                    if((datos1 = open(path, O_RDONLY, 00600)) == -1){error("Failed to open file");} //Opens the target file of Dir1 to copy inside Dir2
                    size = lseek(datos1,0,SEEK_END);
                    if (size > Pos) //Check if the size of the file is bigger than the position that indicates the point from which to start copying the file
                    {
                        lseek(datos1,Pos,SEEK_SET); //Moves the pointer to the start position of the file1
                        if((datos2 = open(path2, O_CREAT|O_WRONLY, 00200)) == -1){error("Error al abrir archivo copia");}
                        lseek(datos2,0,SEEK_SET);
                        j = BS;
                        i = 0;
                        int n = 0;
                        if ((size - i) < BS)
                        {
                            j = size - i;
                        }
                        while ((n = read(datos1, buf, BS)) > 0)
                        {
                            n = write(datos2, buf, j);
                            i = i + n;
                            if ((size - i) < BS)
                            {
                                j = size - i;
                            }
                        }
                        close(datos1);
                        close(datos2);
                    }
                }
            }
        }
    }
    closedir(dir1);
    closedir(dir2); // <-- changed call
    return 0;
}