hr1z0n
hr1z0n

Reputation: 9

Error: Seg. Fault. Want to copy multiple files

I wanted to copy multiple files using multi-threading. This ends in error: segmentation fault. Cannot figure out where.

What I tried: print("test"); on different lines, but gives me the same error. I think the main function is correct, something in the start_routine() block.

Code:

typedef struct filePair
{
    char srcName[100];
    char dstName[100];
} filePair;

void * start_routine(void *arg) //file handling using system calls
{
    char tmp;

    printf("Copying %s to %s.\n", ((filePair *)arg)->srcName, ((filePair *)arg)->dstName);

    int src = open(((filePair *)arg)->srcName, O_RDWR); //open source file
    if (!src)
    {
        printf("Cannot open source file.\n"); //error handling
        exit(0);
    }

    //open dst file
    int dst = open(((filePair *)arg)->dstName, O_WRONLY | O_CREAT, 0641);
    if (!dst)
    {
        printf("Error in destination file.\n"); //error handling
        exit(0);
    }

    while (read(src, &tmp, 1)) //while loop to copy contents
        write(dst, &tmp, 1);

    close(src); //close src and dst files
    close(dst);

    return NULL;
}

//main function...

Upvotes: 0

Views: 66

Answers (2)

Mahammad Iqbal
Mahammad Iqbal

Reputation: 11

1.cause of segmentation fault in code is improper usage of pointers. creating pointers of type filePair and not allocating sufficient memory for those pointers will cause segmentation fault. If we allocate sufficient memory for those pointers, it won't be a problem anymore.

  1. prototype for pthread_create() is

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

before passing *file1 in pthread_create() we should typecast file1 pointer to be of type (void *).

Here I am providing a simple version without using pointers for filePair, but using filePair instances instead.

#include <stdio.h>     /* printf, stderr */
#include <sys/types.h> /* pid_t */
#include <unistd.h>    /* fork */
#include <stdlib.h>    /* atoi */
#include <errno.h>     /* errno */
#include <pthread.h>   /* pthread */
#include <sys/stat.h>
#include <fcntl.h> /* file handling */
#include <time.h>  /* CLOCK */
#include <string.h>

typedef struct
{
    char srcName[100];
    char dstName[100];
} filePair;

void * start_routine(void *arg) //file handling using system calls
{
    char tmp;

    printf("Copying %s to %s.\n", ((filePair *)arg)->srcName, ((filePair *)arg)->dstName);

    int src = open(((filePair *)arg)->srcName, O_RDWR); //open source file
    if (!src)
    {
        printf("Cannot open source file.\n"); //error handling
        exit(0);
    }

    //open dst file
    int dst = open(((filePair *)arg)->dstName, O_WRONLY | O_CREAT, 0641);
    if (!dst)
    {
        printf("Error in destination file.\n"); //error handling
        exit(0);
    }

    while (read(src, &tmp, 1)) //while loop to copy contents
        write(dst, &tmp, 1);

    close(src); //close src and dst files
    close(dst);

    return NULL;
}


/* main function */
int main(int argc, char *argv[])
{
    pthread_t thread1; //Threads init
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
    pthread_t thread5;

    filePair  file1;
    strcpy(file1.srcName, "file1.dat");
    strcpy(file1.dstName, "copy1.dat");

    filePair  file2;
    strcpy(file2.srcName, "file2.dat");
    strcpy(file2.dstName, "copy2.dat");

    filePair  file3;
    strcpy(file3.srcName, "file3.dat");
    strcpy(file3.dstName, "copy3.dat");

    filePair  file4;
    strcpy(file4.srcName, "file4.dat");
    strcpy(file4.dstName, "copy4.dat");

    filePair  file5;
    strcpy(file5.srcName, "file5.dat");
    strcpy(file5.dstName, "copy5.dat");

    printf("\n Before threading.\n\n");

    //Creating threads
    pthread_create(&thread1, NULL, start_routine, (void *)&file1);
    pthread_create(&thread2, NULL, start_routine, (void *)&file2);
    pthread_create(&thread3, NULL, start_routine, (void *)&file3);
    pthread_create(&thread4, NULL, start_routine, (void *)&file4);
    pthread_create(&thread5, NULL, start_routine, (void *)&file5);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_join(thread3, NULL);
    pthread_join(thread4, NULL);
    pthread_join(thread5, NULL);

    printf("\n After threading.\n\n");

    return 0;
}

Upvotes: 1

Mureinik
Mureinik

Reputation: 312289

The name of the type is struct filePair. A common way to make the usage of the type shorter is to incorporate a typedef:

typedef struct
{
    char src[100];
    char dst[100];
} filePair;

Then, you can refer to teh filePair type.

Upvotes: 1

Related Questions