I'm attempting to copy the data from one file by writing it to memory and then copy it into another using memcpy but I'm stumped. I cannot get it to stop giving me segmentation fault. I have a feeling it has something to do with the allocated memory, but I also made sure the file size of the output file is the same as the first one so it wouldn't have that problem and can paste the data into it.
edit: I've come to figure it has to do with char out_data and how I'm attempting to copy data into it when it is read only. Not sure how to go about this.
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <chrono>
using namespace std;
using namespace std::chrono;
#define OUTPUT_MODE 0700 // protection bits for output file
int main(int argc, char** argv)
{
auto start = high_resolution_clock::now();
/* Open the specified file */
int fd = open(argv[1], O_RDWR);
// stats.st_size is a variable containing the size of inFile.txt
struct stat instats;
if (stat(argv[1], &instats)==0)
cout<<endl<<"inFile size "<<instats.st_size;
else
cout<<"Unable to get file properties.\n";
/* Get the page size */
int pagesize = getpagesize();
cout<<endl<<"page size is " <<pagesize<<"\n";
/******************Creation of outFile.txt******************/
int out_fd = creat(argv[2], OUTPUT_MODE);
char* in_data = (char*)mmap(NULL, instats.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
ftruncate(out_fd, instats.st_size);
char* out_data = (char*)mmap(NULL, instats.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, out_fd, 0);
// THIS LINE IS THE CULPRIT
memcpy(out_data, in_data, instats.st_size);
/* Unmap the shared memory region */
munmap(in_data, instats.st_size);
munmap(out_data, instats.st_size);
/* Close the file */
close(fd);
close(out_fd);
return 0;
}
creat
creates a file which is only open for writing. You cannot mmap
such a file descriptor because there is no such thing as write-only memory. If you were to check the return value from the mmap
of out_fd
, you would find that it failed, with errno == EACCES
. When mmap
fails it returns an invalid pointer MAP_FAILED
(not NULL but typically -1
) which causes a segfault when memcpy
attempts to write there.
Note that if (!out_data)
is therefore the wrong test for failure of mmap
; you must use if (out_data == MAP_FAILED)
.
Instead of creat
, use open(argv[2], O_RDWR | O_CREAT | O_TRUNC, OUTPUT_MODE)
.