/* Программа для иллюстрации работы с memory mapped файлом*/


int main(void)
{


int fd;
/* Файловый дескриптор для файла, в котором будет храниться наша информация*/
size_t length;
/* Длина отображаемой части файла */
int i;

/* Ниже следует описание типа структуры, которыми мы забъем файл, и двух указателей на подобный тип. Указатель ptr будет использоваться в качестве начального адреса выделенной области памяти, а указатель tmpptr для перемещения внутри этой области. */

struct A {
double f;
double f2;
} *ptr, *tmpptr;

/* Открываем файл с одновремееным его созданием (если такого файла не было). Права доступа к файлу при создании определяем как read-write для всех категорий пользователей (0666). Из-за ошибки в Linux, мы будем вынуждены ниже в системном вызове mmap() разрешить в отображении файла и чтение, и запись, хотя реально нам нужна только запись. Поэтому и при открытии файла мы вынуждены задавать O_RDWR. */

fd = open("mapped.dat", O_RDWR | O_CREAT, 0666);

if( fd == -1){

/* Если файл открыть не удалось, выдаем сообщение об ошибке и завершаем работу */

printf("File open failed!\n");
exit(1);
}

/* Вычисляем будущую длину файла (мы собираемся записать в него 100000 структур) */

length = 100000*sizeof(struct A);

/* Вновь созданный файл имеет длину 0. Если мы его отобразим в память с такой длиной файла, то любая попытка записи в выделенную память приведет к ошибке. Увеличиваем длину файла до требуемой с помощью вызова ftruncate(). */

ftruncate(fd,length);

/* Отображаем файл в память. Разрешенные операции над отображением указываем как PROT_WRITE | PROT_READ по уже сказанным причинам. Значение флагов ставим в MAP_SHARED, так как мы хотим сохранить информацию, которую занесем в отображение, на диске. Файл отображаем с его начала (offset = 0) и до конца (length = длине файла). */

ptr = (struct A *)mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);

/* Файловый дескриптор нам более не нужен, и мы его закрываем */

close(fd);

if( ptr == MAP_FAILED ){

/* Если отобразить файл не удалось, сообщаем об ошибке и завершаем работу */

printf("Mapping failed!\n");
exit(2);
}

/* В цикле заполняем образ файла числами от 1 до 100000 и их квадратами. Для перемещения по области памяти используем указатель tmpptr, так как указатель ptr на начало образа файла нам понадобится для преращения отображения вызовом munmap(). */

tmpptr = ptr;
for(i = 1; i <=100000; i++){
tmpptr->f = i;
tmpptr->f2 = tmpptr->f*tmpptr->f;
tmpptr++;
}

/* Прекращаем отображать файл в память, записываем содержимое отображения на диск и освобождаем память. */

munmap((void *)ptr, length);
return 0;
}