I need to open a file and load it in shared memory via mmap, but if the file does not exist yet, I want to open it, write some (fake) data to it, and then mmap it. I wrote the following function in C, but I'm getting an error in the write (see below). (I know the mmap part is probably wrong (data is assigned twice!), but the error happens before that, so it should not have any influence on this issue).
// These 2 are global so they can be referenced in other functions.
int dfd = -1;
long* data = NULL;
void load_data(char* filename)
{
dfd = open(filename, O_RDONLY);
if (dfd == -1) {
printf("Creating file %s\n", filename);
dfd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
if (dfd == -1) {
fprintf(stderr, "Couldn't create file %s\n", filename);
perror("create");
exit(1);
}
data = (long *) valloc(M * GB);
if (data == nullptr) {
fprintf(stderr, "Couldn't allocate %ld bytes", (M * GB));
perror("malloc");
exit(1);
}
for (size_t i = 0; i < M * GB / sizeof(long); ++i)
data[i] = (long) i;
printf("%d %p %ld\n", dfd, data, M * GB);
ssize_t w = write(dfd, (void*) data, M * GB);
if (w != M * GB) {
fprintf(stderr, "Couldn't write %ld bytes to file %s\n", (M * GB), filename);
fprintf(stderr, "Wrote %ld bytes\n", w);
perror("write");
exit(1);
}
}
data = (long *) mmap(0, M * GB, PROT_READ, MAP_SHARED, dfd, 0);
if (data == MAP_FAILED) {
perror("mmap");
exit(1);
}
}
Output and error on MacOS 64 bits, Apple g++:
Creating file bench2_datafile.bin
3 0x101441000 2147483648
Couldn't write 2147483648 bytes to file bench2_datafile.bin
Wrote -1 bytes
write: Invalid argument
Any pointer? I keep reading the open and write doc, and looking for examples on the internet, but I can't seem to get over this error.
After benefiting from comments:
Output on RHEL 6, g++ 4.8:
Creating file bench2_datafile.bin
3 0x7f79048af000 2147483648
write: Success
Couldn't write 2147483648 bytes to file bench2_datafile.bin
Wrote 2147479552 bytes
and 2147479552 is indeed the file size in ls.
Also, it works on Mac with 1 GB - but it runs out of steam with 2 GB. Oh well - my real target is Linux anyway, it was just more convenient to work on the Mac till I got the bugs out :-)