Search code examples
cmmapmemory-mapped-files

Why can't I write to the file mmaped


First I create a file and echo some characters to it, and cat the file it shows:

sasdfasdfas

asfdasfsadf

Then in the C program, I open the file with :

int fd=open("file",O_RDWR);

mmaped the file with:

unsigned char *addr=mmap(NULL,length,PROT_WRITE,MAP_PRIVATE,fd,pa_offset);

where length is a int about the size of the file abtained by fstat, and pa_offset is 0.

The open function and mmap function all return well, that are, the open returns a positive integer like 3, and the mmap returns a proper address like 0x7fd36999d000.

I read the file from the addr and everything is OK. When I write to it, it seems write succesfully as I print the memory in the program, but the actual file content is not changed if I cat it.

I have tried some efforts like using msync(), but all have the same result.

Who of you would be kind to tell me where I was stumbled? I just want to write to the file from mmap-_-


Solution

  • You want MAP_SHARED rather than MAP_PRIVATE.

    unsigned char *addr=mmap(NULL,length,PROT_WRITE,MAP_PRIVATE,fd,pa_offset);
                                                    ↑↑↑↑↑↑↑↑↑↑↑
    

    From the GNU C library manual (emphasis mine):

    MAP_PRIVATE - This specifies that writes to the region should never be written back to the attached file. Instead, a copy is made for the process, and the region will be swapped normally if memory runs low. No other process will see the changes.

    MAP_SHARED - This specifies that writes to the region will be written back to the file. Changes made will be shared immediately with other processes mmaping the same file. Note that actual writing may take place at any time. You need to use msync, described below, if it is important that other processes using conventional I/O get a consistent view of the file.

    See man mmap.

    Put another way, MAP_PRIVATE divorces the mapped memory from the backing file by using copy-on-write.