Reputation: 9
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
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.
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
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