3

I need to make some stream in and out classes using mmap() in Linux. To do so I tried to make some test code that writes some integers to a file, saves it, loads it again and write the data in the file to cout. If that test code works, then It wont be a problem making stream in and out afterwards.

When I first started out I got segment faults and If I did not get that nothing happened, so I googled a little. I found this book http://www.advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdf where around page 107 there is some usefull code. I copy pasted that code and made some small changes and got this code:

int fd;
void* file_memory;

/* Prepare a file large enough to hold an unsigned integer.  */
fd = open ("mapTester", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

//Make the file big enough
lseek (fd, 4 * 10 + 1, SEEK_SET);
write (fd, "", 1);
lseek (fd, 0, SEEK_SET);

/* Create the memory mapping.  */
file_memory = mmap (0, 4 * 10, PROT_WRITE, MAP_SHARED, fd, 0);
close (fd);

/* Write a random integer to memory-mapped area.  */
sprintf((char*) file_memory, "%d\n", 22);

/* Release the memory (unnecessary because the program exits).  */
munmap (file_memory, 4 * 10);

cout << "Mark" << endl;

//Start the part where I read from the file

int integer;

/* Open the file.  */
fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);

/* Create the memory mapping.  */
file_memory = mmap (0, 4 * 10, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
close (fd);

/* Read the integer, print it out, and double it.  */
scanf ((char *) file_memory, "%d", &integer);
printf ("value: %d\n", integer);
sprintf ((char*) file_memory, "%d\n", 2 * integer);

/* Release the memory (unnecessary because the program exits).  */
munmap (file_memory, 4 * 10);

But I get a segment fults after the "mark" cout.

Then I replace the "read part" with this:

fd = open("mapTester", O_RDONLY);

int* buffer = (int*) malloc (4*10);

read(fd, buffer, 4 * 10);

for(int i = 0; i < 1; i++)
{
    cout << buffer[i] << endl;
}

That is some working code that shows me that the file is empty. I tries out a couple of ways to write to the mapping without any change in result.

So how am I amble to make my code write? And does my mmap read code seem okay (just in case you can see some obvious flaws)?

I have found some other resources that did not help me yet, but because I am a new user I may only post max 2 links.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
RobbingDaHood
  • 150
  • 2
  • 2
  • 12

2 Answers2

4

You should test the result of mmap. If it gives MAP_FAILED check out errno to find out why.

And you'll better mmap a multiple of pages, often 4K bytes each, and given by sysconf(_SC_PAGESIZE)

You can use stat to find out the size of (and many other numbers about) some given file.

You could use strace on existing Linux programs to learn what syscalls they are doing.

See also this about /proc/ etc.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    Thank you for the help, I found out that the file i wrote to where write protected and because of that everything failed. – RobbingDaHood Feb 14 '12 at 13:58
1

Your scanf() call should be sscanf(), and the second open should use "mapTester" instead of argv[1] as the filename. When I fix these bugs, your posted program works (printing out 22 and leaving 44 in the file).

caf
  • 233,326
  • 40
  • 323
  • 462
  • I could not get the code working with the changes you said. I dont know how to format code in a comment so I just put it at the end of the message. I use the g++ compiler command, maybe you are using another one? – RobbingDaHood Feb 14 '12 at 13:39
  • Okay I cant add more code, because it is to long. I copied the code i wrote in here and changed the 2 places and it came with a segmentation fault in the last part of the code. But thanks for the 2 good sugestion, very helpful :) – RobbingDaHood Feb 14 '12 at 13:41