I want to use mmap()
to create a file containing some integers. I want to write to this file by writing to memory. I know that the data in memory is binary format and hence the data in file will also be in binary.
Can I use mmap
for this purpose? where can I find good resources on how to use mmap
? I didn't find a good manual to start with.
Asked
Active
Viewed 7.9k times
15

parisa
- 784
- 1
- 8
- 27
-
8`man 2 mmap` will pretty much tell you everything you need to know. – Daniel Kamil Kozar Oct 08 '14 at 14:28
-
5other way around. you create a file, then mmap it. then any access to the memory occupied by that file will automatically be written out to the on-disk file. – Marc B Oct 08 '14 at 14:29
-
2Note that if you ware writing memory-integers using mmap to a file, the byte ordering on different platforms can keep those files from being able to be exchanged between different architectures that run your program. If that matters to you, [try looking at this question](http://stackoverflow.com/questions/1025783/mmap-big-endian-vs-little-endian) – HostileFork says dont trust SE Oct 08 '14 at 14:38
-
@MarcB: Automatically, but not immediately. The system writes it to the disk only when it needs to free some physical memory and it needs to swap that memory off to disk. Until then, changes in memory are not autimatically visible in the file and doesn't affect the file in any way (heck, it may not affect it at all if one used `MAP_PRIVATE`!). The data is saved to disk on `munmap` or when you specifically request it with `msync`. – SasQ Sep 08 '20 at 06:34
2 Answers
16
Here is an example:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h> /* mmap() is defined in this header */
#include <fcntl.h>
#include <stdio.h>
void err_quit(char *msg)
{
printf(msg);
return 0;
}
int main (int argc, char *argv[])
{
int fdin, fdout;
char *src, *dst;
struct stat statbuf;
int mode = 0x0777;
if (argc != 3)
err_quit ("usage: a.out <fromfile> <tofile>");
/* open the input file */
if ((fdin = open (argv[1], O_RDONLY)) < 0)
{printf("can't open %s for reading", argv[1]);
return 0;
}
/* open/create the output file */
if ((fdout = open (argv[2], O_RDWR | O_CREAT | O_TRUNC, mode )) < 0)//edited here
{printf ("can't create %s for writing", argv[2]);
return 0;
}
/* find size of input file */
if (fstat (fdin,&statbuf) < 0)
{printf ("fstat error");
return 0;
}
/* go to the location corresponding to the last byte */
if (lseek (fdout, statbuf.st_size - 1, SEEK_SET) == -1)
{printf ("lseek error");
return 0;
}
/* write a dummy byte at the last location */
if (write (fdout, "", 1) != 1)
{printf ("write error");
return 0;
}
/* mmap the input file */
if ((src = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0))
== (caddr_t) -1)
{printf ("mmap error for input");
return 0;
}
/* mmap the output file */
if ((dst = mmap (0, statbuf.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fdout, 0)) == (caddr_t) -1)
{printf ("mmap error for output");
return 0;
}
/* this copies the input file to the output file */
memcpy (dst, src, statbuf.st_size);
return 0;
} /* main */
From Here
Another Linux example
Windows implementation of memory mapping.

ryyker
- 22,849
- 3
- 43
- 87
-
Thanks. When I want to compile it I get this error: " error: ‘FILE_MODE’ undeclared (first use in this function)". – parisa Oct 08 '14 at 14:40
-
-
2
-
I am not currently on a Linux machine. Here is a ***[link](http://lxr.free-electrons.com/ident?v=2.6.34;i=file_mode)*** – ryyker Oct 08 '14 at 14:48
-
1FILE_MODE should contain the permissions, set it to FILE_MODE = 0x0777 for example. – ryyker Oct 08 '14 at 14:51
-
-
-
1
-
-
-
For purposes of this sample you can either comment these lines, or change them both to printf("message"); They are there as place holders for error conditions. – ryyker Oct 08 '14 at 15:01
-
err_quit could be defined as: `void err_quit(char *msg);` See edit in 1 minute. – ryyker Oct 08 '14 at 15:05
-
All `err_sys` have been changed to `printf` with `return` statement. Should build now. – ryyker Oct 08 '14 at 15:15
-
1
2
Ressources -> mmap man 2
Examples : Linux's cp by fahmy
if ((dst = mmap (0, statbuf.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fdout, 0)) == (caddr_t) -1)
err_sys ("mmap error for output");
/* this copies the input file to the output file */
memcpy (dst, src, statbuf.st_size);
#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* Does not work on OS X, as you can't mmap over /dev/zero */
int main(void)
{
const char str1[] = "string 1";
const char str2[] = "string 2";
int parpid = getpid(), childpid;
int fd = -1;
char *anon, *zero;
if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
err(1, "open");
anon = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
zero = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);
if (anon == MAP_FAILED || zero == MAP_FAILED)
errx(1, "either mmap");
strcpy(anon, str1);
strcpy(zero, str1);
printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
switch ((childpid = fork())) {
case -1:
err(1, "fork");
/* NOTREACHED */
case 0:
childpid = getpid();
printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
sleep(3);
printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
munmap(anon, 4096);
munmap(zero, 4096);
close(fd);
return (EXIT_SUCCESS);
}
sleep(2);
strcpy(anon, str2);
strcpy(zero, str2);
printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
munmap(anon, 4096);
munmap(zero, 4096);
close(fd);
return (EXIT_SUCCESS);
}
Try using both and adapt them for your goal.

Mekap
- 2,065
- 14
- 26
-
1While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – djv Oct 08 '14 at 15:06
-
2@Verdolino Hi, i followed your advices and reworked my answer. Thanks for your input ! – Mekap Apr 28 '15 at 08:45